diff --git a/api/client/client.go b/api/client/client.go index 162fa08a3aea5..41311370dd8e3 100644 --- a/api/client/client.go +++ b/api/client/client.go @@ -89,6 +89,7 @@ import ( oktapb "github.com/gravitational/teleport/api/gen/proto/go/teleport/okta/v1" pluginspb "github.com/gravitational/teleport/api/gen/proto/go/teleport/plugins/v1" presencepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/presence/v1" + recordingencryptionv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" recordingmetadatav1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingmetadata/v1" resourceusagepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/resourceusage/v1" samlidppb "github.com/gravitational/teleport/api/gen/proto/go/teleport/samlidp/v1" @@ -130,6 +131,7 @@ type AuthServiceClient struct { auditlogpb.AuditLogServiceClient userpreferencespb.UserPreferencesServiceClient notificationsv1pb.NotificationServiceClient + recordingencryptionv1pb.RecordingEncryptionServiceClient } // Client is a gRPC Client that connects to a Teleport Auth server either @@ -539,10 +541,11 @@ func (c *Client) dialGRPC(ctx context.Context, addr string) error { c.conn = conn c.grpc = AuthServiceClient{ - AuthServiceClient: proto.NewAuthServiceClient(c.conn), - AuditLogServiceClient: auditlogpb.NewAuditLogServiceClient(c.conn), - UserPreferencesServiceClient: userpreferencespb.NewUserPreferencesServiceClient(c.conn), - NotificationServiceClient: notificationsv1pb.NewNotificationServiceClient(c.conn), + AuthServiceClient: proto.NewAuthServiceClient(c.conn), + AuditLogServiceClient: auditlogpb.NewAuditLogServiceClient(c.conn), + UserPreferencesServiceClient: userpreferencespb.NewUserPreferencesServiceClient(c.conn), + NotificationServiceClient: notificationsv1pb.NewNotificationServiceClient(c.conn), + RecordingEncryptionServiceClient: recordingencryptionv1pb.NewRecordingEncryptionServiceClient(c.conn), } c.JoinServiceClient = NewJoinServiceClient(proto.NewJoinServiceClient(c.conn)) @@ -951,6 +954,12 @@ func (c *Client) RecordingMetadataServiceClient() recordingmetadatav1.RecordingM return recordingmetadatav1.NewRecordingMetadataServiceClient(c.conn) } +// RecordingEncryptionServiceClient returns an unadorned client for the session +// recording encryption service. +func (c *Client) RecordingEncryptionServiceClient() recordingencryptionv1pb.RecordingEncryptionServiceClient { + return recordingencryptionv1pb.NewRecordingEncryptionServiceClient(c.conn) +} + // GetVnetConfig returns the singleton VnetConfig resource. func (c *Client) GetVnetConfig(ctx context.Context) (*vnet.VnetConfig, error) { return c.VnetConfigServiceClient().GetVnetConfig(ctx, &vnet.GetVnetConfigRequest{}) @@ -2554,6 +2563,45 @@ func (c *Client) StreamSessionEvents(ctx context.Context, sessionID string, star return ch, e } +// UploadEncryptedRecording streams encrypted recording parts to the auth +// server to be saved in long term storage. +func (c *Client) UploadEncryptedRecording(ctx context.Context, sessionID string, parts iter.Seq2[[]byte, error]) error { + createRes, err := c.grpc.CreateUpload(ctx, &recordingencryptionv1pb.CreateUploadRequest{ + SessionId: sessionID, + }) + if err != nil { + return trace.Wrap(err) + } + + var uploadedParts []*recordingencryptionv1pb.Part + var partNumber int64 + for part, err := range parts { + if err != nil { + return trace.Wrap(err) + } + + uploadRes, err := c.grpc.UploadPart(ctx, &recordingencryptionv1pb.UploadPartRequest{ + Upload: createRes.Upload, + PartNumber: partNumber, + Part: part, + }) + if err != nil { + return trace.Wrap(err) + } + uploadedParts = append(uploadedParts, uploadRes.Part) + partNumber++ + } + + if _, err := c.grpc.CompleteUpload(ctx, &recordingencryptionv1pb.CompleteUploadRequest{ + Upload: createRes.Upload, + Parts: uploadedParts, + }); err != nil { + return trace.Wrap(err) + } + + return nil +} + // SearchEvents allows searching for events with a full pagination support. func (c *Client) SearchEvents(ctx context.Context, fromUTC, toUTC time.Time, namespace string, eventTypes []string, limit int, order types.EventOrder, startKey string) ([]events.AuditEvent, string, error) { request := &proto.GetEventsRequest{ diff --git a/api/client/events.go b/api/client/events.go index 3072e9a651fb6..5658f6eaf9b4c 100644 --- a/api/client/events.go +++ b/api/client/events.go @@ -29,6 +29,7 @@ import ( machineidv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/machineid/v1" notificationsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/notifications/v1" provisioningv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/provisioning/v1" + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" accessv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/scopes/access/v1" userprovisioningpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2" usertasksv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/usertasks/v1" @@ -156,6 +157,10 @@ func EventToGRPC(in types.Event) (*proto.Event, error) { out.Resource = &proto.Event_WorkloadIdentityX509Revocation{ WorkloadIdentityX509Revocation: r.UnwrapT(), } + case types.Resource153UnwrapperT[*recordingencryptionv1.RecordingEncryption]: + out.Resource = &proto.Event_RecordingEncryption{ + RecordingEncryption: r.UnwrapT(), + } case types.Resource153UnwrapperT[*healthcheckconfigv1.HealthCheckConfig]: out.Resource = &proto.Event_HealthCheckConfig{ HealthCheckConfig: r.UnwrapT(), @@ -660,6 +665,9 @@ func EventFromGRPC(in *proto.Event) (*types.Event, error) { } else if r := in.GetPlugin(); r != nil { out.Resource = r return &out, nil + } else if r := in.GetRecordingEncryption(); r != nil { + out.Resource = types.ProtoResource153ToLegacy(r) + return &out, nil } else { return nil, trace.BadParameter("received unsupported resource %T", in.Resource) } diff --git a/api/client/proto/event.pb.go b/api/client/proto/event.pb.go index 05ed57ca128ba..f624d6f9d9478 100644 --- a/api/client/proto/event.pb.go +++ b/api/client/proto/event.pb.go @@ -34,6 +34,7 @@ import ( v19 "github.com/gravitational/teleport/api/gen/proto/go/teleport/machineid/v1" v16 "github.com/gravitational/teleport/api/gen/proto/go/teleport/notifications/v1" v113 "github.com/gravitational/teleport/api/gen/proto/go/teleport/provisioning/v1" + v118 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" v117 "github.com/gravitational/teleport/api/gen/proto/go/teleport/scopes/access/v1" v13 "github.com/gravitational/teleport/api/gen/proto/go/teleport/secreports/v1" v11 "github.com/gravitational/teleport/api/gen/proto/go/teleport/userloginstate/v1" @@ -194,6 +195,7 @@ type Event struct { // *Event_AutoUpdateAgentReport // *Event_ScopedRole // *Event_ScopedRoleAssignment + // *Event_RecordingEncryption // *Event_Plugin Resource isEvent_Resource `protobuf_oneof:"Resource"` unknownFields protoimpl.UnknownFields @@ -928,6 +930,15 @@ func (x *Event) GetScopedRoleAssignment() *v117.ScopedRoleAssignment { return nil } +func (x *Event) GetRecordingEncryption() *v118.RecordingEncryption { + if x != nil { + if x, ok := x.Resource.(*Event_RecordingEncryption); ok { + return x.RecordingEncryption + } + } + return nil +} + func (x *Event) GetPlugin() *types.PluginV1 { if x != nil { if x, ok := x.Resource.(*Event_Plugin); ok { @@ -1327,6 +1338,11 @@ type Event_ScopedRoleAssignment struct { ScopedRoleAssignment *v117.ScopedRoleAssignment `protobuf:"bytes,81,opt,name=ScopedRoleAssignment,proto3,oneof"` } +type Event_RecordingEncryption struct { + // RecordingEncryption is a resource for controlling session recording encryption. + RecordingEncryption *v118.RecordingEncryption `protobuf:"bytes,83,opt,name=RecordingEncryption,proto3,oneof"` +} + type Event_Plugin struct { // PluginV1 is a resource for Teleport plugins. Plugin *types.PluginV1 `protobuf:"bytes,84,opt,name=plugin,proto3,oneof"` @@ -1484,13 +1500,15 @@ func (*Event_ScopedRole) isEvent_Resource() {} func (*Event_ScopedRoleAssignment) isEvent_Resource() {} +func (*Event_RecordingEncryption) isEvent_Resource() {} + func (*Event_Plugin) isEvent_Resource() {} var File_teleport_legacy_client_proto_event_proto protoreflect.FileDescriptor const file_teleport_legacy_client_proto_event_proto_rawDesc = "" + "\n" + - "(teleport/legacy/client/proto/event.proto\x12\x05proto\x1a'teleport/accesslist/v1/accesslist.proto\x1a?teleport/accessmonitoringrules/v1/access_monitoring_rules.proto\x1a'teleport/autoupdate/v1/autoupdate.proto\x1a5teleport/clusterconfig/v1/access_graph_settings.proto\x1a'teleport/crownjewel/v1/crownjewel.proto\x1a#teleport/dbobject/v1/dbobject.proto\x1a1teleport/discoveryconfig/v1/discoveryconfig.proto\x1a7teleport/healthcheckconfig/v1/health_check_config.proto\x1a/teleport/identitycenter/v1/identitycenter.proto\x1a;teleport/kubewaitingcontainer/v1/kubewaitingcontainer.proto\x1a!teleport/legacy/types/types.proto\x1a(teleport/machineid/v1/bot_instance.proto\x1a&teleport/machineid/v1/federation.proto\x1a-teleport/notifications/v1/notifications.proto\x1a+teleport/provisioning/v1/provisioning.proto\x1a*teleport/scopes/access/v1/assignment.proto\x1a$teleport/scopes/access/v1/role.proto\x1a'teleport/secreports/v1/secreports.proto\x1a/teleport/userloginstate/v1/userloginstate.proto\x1a1teleport/userprovisioning/v2/statichostuser.proto\x1a&teleport/usertasks/v1/user_tasks.proto\x1a+teleport/workloadidentity/v1/resource.proto\x1a6teleport/workloadidentity/v1/revocation_resource.proto\"\xb8.\n" + + "(teleport/legacy/client/proto/event.proto\x12\x05proto\x1a'teleport/accesslist/v1/accesslist.proto\x1a?teleport/accessmonitoringrules/v1/access_monitoring_rules.proto\x1a'teleport/autoupdate/v1/autoupdate.proto\x1a5teleport/clusterconfig/v1/access_graph_settings.proto\x1a'teleport/crownjewel/v1/crownjewel.proto\x1a#teleport/dbobject/v1/dbobject.proto\x1a1teleport/discoveryconfig/v1/discoveryconfig.proto\x1a7teleport/healthcheckconfig/v1/health_check_config.proto\x1a/teleport/identitycenter/v1/identitycenter.proto\x1a;teleport/kubewaitingcontainer/v1/kubewaitingcontainer.proto\x1a!teleport/legacy/types/types.proto\x1a(teleport/machineid/v1/bot_instance.proto\x1a&teleport/machineid/v1/federation.proto\x1a-teleport/notifications/v1/notifications.proto\x1a+teleport/provisioning/v1/provisioning.proto\x1a:teleport/recordingencryption/v1/recording_encryption.proto\x1a*teleport/scopes/access/v1/assignment.proto\x1a$teleport/scopes/access/v1/role.proto\x1a'teleport/secreports/v1/secreports.proto\x1a/teleport/userloginstate/v1/userloginstate.proto\x1a1teleport/userprovisioning/v2/statichostuser.proto\x1a&teleport/usertasks/v1/user_tasks.proto\x1a+teleport/workloadidentity/v1/resource.proto\x1a6teleport/workloadidentity/v1/revocation_resource.proto\"\xa2/\n" + "\x05Event\x12$\n" + "\x04Type\x18\x01 \x01(\x0e2\x10.proto.OperationR\x04Type\x12?\n" + "\x0eResourceHeader\x18\x02 \x01(\v2\x15.types.ResourceHeaderH\x00R\x0eResourceHeader\x12>\n" + @@ -1581,7 +1599,8 @@ const file_teleport_legacy_client_proto_event_proto_rawDesc = "" + "\n" + "ScopedRole\x18P \x01(\v2%.teleport.scopes.access.v1.ScopedRoleH\x00R\n" + "ScopedRole\x12e\n" + - "\x14ScopedRoleAssignment\x18Q \x01(\v2/.teleport.scopes.access.v1.ScopedRoleAssignmentH\x00R\x14ScopedRoleAssignment\x12)\n" + + "\x14ScopedRoleAssignment\x18Q \x01(\v2/.teleport.scopes.access.v1.ScopedRoleAssignmentH\x00R\x14ScopedRoleAssignment\x12h\n" + + "\x13RecordingEncryption\x18S \x01(\v24.teleport.recordingencryption.v1.RecordingEncryptionH\x00R\x13RecordingEncryption\x12)\n" + "\x06plugin\x18T \x01(\v2\x0f.types.PluginV1H\x00R\x06pluginB\n" + "\n" + "\bResourceJ\x04\b\a\x10\bJ\x04\b1\x102J\x04\b?\x10@J\x04\bD\x10ER\x12ExternalCloudAuditR\x0eStaticHostUserR\x13AutoUpdateAgentPlan**\n" + @@ -1681,7 +1700,8 @@ var file_teleport_legacy_client_proto_event_proto_goTypes = []any{ (*v111.AutoUpdateAgentReport)(nil), // 72: teleport.autoupdate.v1.AutoUpdateAgentReport (*v117.ScopedRole)(nil), // 73: teleport.scopes.access.v1.ScopedRole (*v117.ScopedRoleAssignment)(nil), // 74: teleport.scopes.access.v1.ScopedRoleAssignment - (*types.PluginV1)(nil), // 75: types.PluginV1 + (*v118.RecordingEncryption)(nil), // 75: teleport.recordingencryption.v1.RecordingEncryption + (*types.PluginV1)(nil), // 76: types.PluginV1 } var file_teleport_legacy_client_proto_event_proto_depIdxs = []int32{ 0, // 0: proto.Event.Type:type_name -> proto.Operation @@ -1761,12 +1781,13 @@ var file_teleport_legacy_client_proto_event_proto_depIdxs = []int32{ 72, // 74: proto.Event.AutoUpdateAgentReport:type_name -> teleport.autoupdate.v1.AutoUpdateAgentReport 73, // 75: proto.Event.ScopedRole:type_name -> teleport.scopes.access.v1.ScopedRole 74, // 76: proto.Event.ScopedRoleAssignment:type_name -> teleport.scopes.access.v1.ScopedRoleAssignment - 75, // 77: proto.Event.plugin:type_name -> types.PluginV1 - 78, // [78:78] is the sub-list for method output_type - 78, // [78:78] is the sub-list for method input_type - 78, // [78:78] is the sub-list for extension type_name - 78, // [78:78] is the sub-list for extension extendee - 0, // [0:78] is the sub-list for field type_name + 75, // 77: proto.Event.RecordingEncryption:type_name -> teleport.recordingencryption.v1.RecordingEncryption + 76, // 78: proto.Event.plugin:type_name -> types.PluginV1 + 79, // [79:79] is the sub-list for method output_type + 79, // [79:79] is the sub-list for method input_type + 79, // [79:79] is the sub-list for extension type_name + 79, // [79:79] is the sub-list for extension extendee + 0, // [0:79] is the sub-list for field type_name } func init() { file_teleport_legacy_client_proto_event_proto_init() } @@ -1851,6 +1872,7 @@ func file_teleport_legacy_client_proto_event_proto_init() { (*Event_AutoUpdateAgentReport)(nil), (*Event_ScopedRole)(nil), (*Event_ScopedRoleAssignment)(nil), + (*Event_RecordingEncryption)(nil), (*Event_Plugin)(nil), } type x struct{} diff --git a/api/gen/proto/go/teleport/recordingencryption/v1/recording_encryption.pb.go b/api/gen/proto/go/teleport/recordingencryption/v1/recording_encryption.pb.go new file mode 100644 index 0000000000000..41be3b7e2f965 --- /dev/null +++ b/api/gen/proto/go/teleport/recordingencryption/v1/recording_encryption.pb.go @@ -0,0 +1,598 @@ +// Copyright 2025 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc (unknown) +// source: teleport/recordingencryption/v1/recording_encryption.proto + +package recordingencryptionv1 + +import ( + v1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + types "github.com/gravitational/teleport/api/types" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The possible states a KeyPair can be in. +type KeyPairState int32 + +const ( + // Unspecified value + KeyPairState_KEY_PAIR_STATE_UNSPECIFIED KeyPairState = 0 + // Represents an active key. + KeyPairState_KEY_PAIR_STATE_ACTIVE KeyPairState = 1 + // Represents a key in the process of being rotated. + KeyPairState_KEY_PAIR_STATE_ROTATING KeyPairState = 2 + // Represents a key being rotated in that is inaccessible to at least one + // auth server. + KeyPairState_KEY_PAIR_STATE_INACCESSIBLE KeyPairState = 3 +) + +// Enum value maps for KeyPairState. +var ( + KeyPairState_name = map[int32]string{ + 0: "KEY_PAIR_STATE_UNSPECIFIED", + 1: "KEY_PAIR_STATE_ACTIVE", + 2: "KEY_PAIR_STATE_ROTATING", + 3: "KEY_PAIR_STATE_INACCESSIBLE", + } + KeyPairState_value = map[string]int32{ + "KEY_PAIR_STATE_UNSPECIFIED": 0, + "KEY_PAIR_STATE_ACTIVE": 1, + "KEY_PAIR_STATE_ROTATING": 2, + "KEY_PAIR_STATE_INACCESSIBLE": 3, + } +) + +func (x KeyPairState) Enum() *KeyPairState { + p := new(KeyPairState) + *p = x + return p +} + +func (x KeyPairState) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (KeyPairState) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_recordingencryption_v1_recording_encryption_proto_enumTypes[0].Descriptor() +} + +func (KeyPairState) Type() protoreflect.EnumType { + return &file_teleport_recordingencryption_v1_recording_encryption_proto_enumTypes[0] +} + +func (x KeyPairState) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use KeyPairState.Descriptor instead. +func (KeyPairState) EnumDescriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescGZIP(), []int{0} +} + +// A key pair used with age to wrap and unwrap file keys for session recording encryption. +type KeyPair struct { + state protoimpl.MessageState `protogen:"open.v1"` + // A key pair used with age to wrap and unwrap file keys for session recording encryption. + KeyPair *types.EncryptionKeyPair `protobuf:"bytes,1,opt,name=key_pair,json=keyPair,proto3" json:"key_pair,omitempty"` + // The current state of the key pair. + State KeyPairState `protobuf:"varint,2,opt,name=state,proto3,enum=teleport.recordingencryption.v1.KeyPairState" json:"state,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *KeyPair) Reset() { + *x = KeyPair{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *KeyPair) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeyPair) ProtoMessage() {} + +func (x *KeyPair) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[0] + 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 KeyPair.ProtoReflect.Descriptor instead. +func (*KeyPair) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescGZIP(), []int{0} +} + +func (x *KeyPair) GetKeyPair() *types.EncryptionKeyPair { + if x != nil { + return x.KeyPair + } + return nil +} + +func (x *KeyPair) GetState() KeyPairState { + if x != nil { + return x.State + } + return KeyPairState_KEY_PAIR_STATE_UNSPECIFIED +} + +// RecordingEncryptionSpec contains the active key set for encrypted session recording. +type RecordingEncryptionSpec struct { + state protoimpl.MessageState `protogen:"open.v1"` + // A list of active key pairs used for session recording encryption. The unique set of + // active public keys are used as recipients during age encryption. This allows any + // active private key to be used during decryption which guards against recordings being + // inaccessible to auth servers waiting for key rotation. + ActiveKeyPairs []*KeyPair `protobuf:"bytes,2,rep,name=active_key_pairs,json=activeKeyPairs,proto3" json:"active_key_pairs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RecordingEncryptionSpec) Reset() { + *x = RecordingEncryptionSpec{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RecordingEncryptionSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecordingEncryptionSpec) ProtoMessage() {} + +func (x *RecordingEncryptionSpec) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[1] + 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 RecordingEncryptionSpec.ProtoReflect.Descriptor instead. +func (*RecordingEncryptionSpec) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescGZIP(), []int{1} +} + +func (x *RecordingEncryptionSpec) GetActiveKeyPairs() []*KeyPair { + if x != nil { + return x.ActiveKeyPairs + } + return nil +} + +// RecordingEncryptionStatus contains the status of the RecordingEncryption resource. +type RecordingEncryptionStatus struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RecordingEncryptionStatus) Reset() { + *x = RecordingEncryptionStatus{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RecordingEncryptionStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecordingEncryptionStatus) ProtoMessage() {} + +func (x *RecordingEncryptionStatus) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[2] + 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 RecordingEncryptionStatus.ProtoReflect.Descriptor instead. +func (*RecordingEncryptionStatus) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescGZIP(), []int{2} +} + +// RecordingEncryption contains cluster state for encrypted session recordings. +type RecordingEncryption struct { + state protoimpl.MessageState `protogen:"open.v1"` + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + SubKind string `protobuf:"bytes,2,opt,name=sub_kind,json=subKind,proto3" json:"sub_kind,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Metadata *v1.Metadata `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"` + Spec *RecordingEncryptionSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` + Status *RecordingEncryptionStatus `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RecordingEncryption) Reset() { + *x = RecordingEncryption{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RecordingEncryption) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecordingEncryption) ProtoMessage() {} + +func (x *RecordingEncryption) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[3] + 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 RecordingEncryption.ProtoReflect.Descriptor instead. +func (*RecordingEncryption) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescGZIP(), []int{3} +} + +func (x *RecordingEncryption) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *RecordingEncryption) GetSubKind() string { + if x != nil { + return x.SubKind + } + return "" +} + +func (x *RecordingEncryption) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *RecordingEncryption) GetMetadata() *v1.Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *RecordingEncryption) GetSpec() *RecordingEncryptionSpec { + if x != nil { + return x.Spec + } + return nil +} + +func (x *RecordingEncryption) GetStatus() *RecordingEncryptionStatus { + if x != nil { + return x.Status + } + return nil +} + +// A rotated key pair previously used with age to wrap and unwrap file keys for session recording +// encryption. +type RotatedKeySpec struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The rotated key pair previously used with age to wrap and unwrap file keys for session recording + // encryption. + EncryptionKeyPair *types.EncryptionKeyPair `protobuf:"bytes,2,opt,name=encryption_key_pair,json=encryptionKeyPair,proto3" json:"encryption_key_pair,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RotatedKeySpec) Reset() { + *x = RotatedKeySpec{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RotatedKeySpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RotatedKeySpec) ProtoMessage() {} + +func (x *RotatedKeySpec) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[4] + 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 RotatedKeySpec.ProtoReflect.Descriptor instead. +func (*RotatedKeySpec) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescGZIP(), []int{4} +} + +func (x *RotatedKeySpec) GetEncryptionKeyPair() *types.EncryptionKeyPair { + if x != nil { + return x.EncryptionKeyPair + } + return nil +} + +// The empty status of a RotatedKey. +type RotatedKeyStatus struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RotatedKeyStatus) Reset() { + *x = RotatedKeyStatus{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RotatedKeyStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RotatedKeyStatus) ProtoMessage() {} + +func (x *RotatedKeyStatus) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[5] + 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 RotatedKeyStatus.ProtoReflect.Descriptor instead. +func (*RotatedKeyStatus) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescGZIP(), []int{5} +} + +// A previously rotated encryption key for session recordings kept for future replay. The metadata.name +// is expected to be the fingerprint of the public key contained in the spec, which is a hex encoded +// SHA256 hash of its PKIX form. +type RotatedKey struct { + state protoimpl.MessageState `protogen:"open.v1"` + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + SubKind string `protobuf:"bytes,2,opt,name=sub_kind,json=subKind,proto3" json:"sub_kind,omitempty"` + Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Metadata *v1.Metadata `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"` + Spec *RotatedKeySpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` + Status *RotatedKeyStatus `protobuf:"bytes,6,opt,name=status,proto3" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RotatedKey) Reset() { + *x = RotatedKey{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RotatedKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RotatedKey) ProtoMessage() {} + +func (x *RotatedKey) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes[6] + 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 RotatedKey.ProtoReflect.Descriptor instead. +func (*RotatedKey) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescGZIP(), []int{6} +} + +func (x *RotatedKey) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *RotatedKey) GetSubKind() string { + if x != nil { + return x.SubKind + } + return "" +} + +func (x *RotatedKey) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *RotatedKey) GetMetadata() *v1.Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *RotatedKey) GetSpec() *RotatedKeySpec { + if x != nil { + return x.Spec + } + return nil +} + +func (x *RotatedKey) GetStatus() *RotatedKeyStatus { + if x != nil { + return x.Status + } + return nil +} + +var File_teleport_recordingencryption_v1_recording_encryption_proto protoreflect.FileDescriptor + +const file_teleport_recordingencryption_v1_recording_encryption_proto_rawDesc = "" + + "\n" + + ":teleport/recordingencryption/v1/recording_encryption.proto\x12\x1fteleport.recordingencryption.v1\x1a!teleport/header/v1/metadata.proto\x1a!teleport/legacy/types/types.proto\"\x83\x01\n" + + "\aKeyPair\x123\n" + + "\bkey_pair\x18\x01 \x01(\v2\x18.types.EncryptionKeyPairR\akeyPair\x12C\n" + + "\x05state\x18\x02 \x01(\x0e2-.teleport.recordingencryption.v1.KeyPairStateR\x05state\"\x80\x01\n" + + "\x17RecordingEncryptionSpec\x12R\n" + + "\x10active_key_pairs\x18\x02 \x03(\v2(.teleport.recordingencryption.v1.KeyPairR\x0eactiveKeyPairsJ\x04\b\x01\x10\x02R\vactive_keys\"\x1b\n" + + "\x19RecordingEncryptionStatus\"\xba\x02\n" + + "\x13RecordingEncryption\x12\x12\n" + + "\x04kind\x18\x01 \x01(\tR\x04kind\x12\x19\n" + + "\bsub_kind\x18\x02 \x01(\tR\asubKind\x12\x18\n" + + "\aversion\x18\x03 \x01(\tR\aversion\x128\n" + + "\bmetadata\x18\x04 \x01(\v2\x1c.teleport.header.v1.MetadataR\bmetadata\x12L\n" + + "\x04spec\x18\x05 \x01(\v28.teleport.recordingencryption.v1.RecordingEncryptionSpecR\x04spec\x12R\n" + + "\x06status\x18\x06 \x01(\v2:.teleport.recordingencryption.v1.RecordingEncryptionStatusR\x06status\"Z\n" + + "\x0eRotatedKeySpec\x12H\n" + + "\x13encryption_key_pair\x18\x02 \x01(\v2\x18.types.EncryptionKeyPairR\x11encryptionKeyPair\"\x12\n" + + "\x10RotatedKeyStatus\"\x9f\x02\n" + + "\n" + + "RotatedKey\x12\x12\n" + + "\x04kind\x18\x01 \x01(\tR\x04kind\x12\x19\n" + + "\bsub_kind\x18\x02 \x01(\tR\asubKind\x12\x18\n" + + "\aversion\x18\x03 \x01(\tR\aversion\x128\n" + + "\bmetadata\x18\x04 \x01(\v2\x1c.teleport.header.v1.MetadataR\bmetadata\x12C\n" + + "\x04spec\x18\x05 \x01(\v2/.teleport.recordingencryption.v1.RotatedKeySpecR\x04spec\x12I\n" + + "\x06status\x18\x06 \x01(\v21.teleport.recordingencryption.v1.RotatedKeyStatusR\x06status*\x87\x01\n" + + "\fKeyPairState\x12\x1e\n" + + "\x1aKEY_PAIR_STATE_UNSPECIFIED\x10\x00\x12\x19\n" + + "\x15KEY_PAIR_STATE_ACTIVE\x10\x01\x12\x1b\n" + + "\x17KEY_PAIR_STATE_ROTATING\x10\x02\x12\x1f\n" + + "\x1bKEY_PAIR_STATE_INACCESSIBLE\x10\x03BjZhgithub.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1;recordingencryptionv1b\x06proto3" + +var ( + file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescOnce sync.Once + file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescData []byte +) + +func file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescGZIP() []byte { + file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescOnce.Do(func() { + file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_teleport_recordingencryption_v1_recording_encryption_proto_rawDesc), len(file_teleport_recordingencryption_v1_recording_encryption_proto_rawDesc))) + }) + return file_teleport_recordingencryption_v1_recording_encryption_proto_rawDescData +} + +var file_teleport_recordingencryption_v1_recording_encryption_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_teleport_recordingencryption_v1_recording_encryption_proto_goTypes = []any{ + (KeyPairState)(0), // 0: teleport.recordingencryption.v1.KeyPairState + (*KeyPair)(nil), // 1: teleport.recordingencryption.v1.KeyPair + (*RecordingEncryptionSpec)(nil), // 2: teleport.recordingencryption.v1.RecordingEncryptionSpec + (*RecordingEncryptionStatus)(nil), // 3: teleport.recordingencryption.v1.RecordingEncryptionStatus + (*RecordingEncryption)(nil), // 4: teleport.recordingencryption.v1.RecordingEncryption + (*RotatedKeySpec)(nil), // 5: teleport.recordingencryption.v1.RotatedKeySpec + (*RotatedKeyStatus)(nil), // 6: teleport.recordingencryption.v1.RotatedKeyStatus + (*RotatedKey)(nil), // 7: teleport.recordingencryption.v1.RotatedKey + (*types.EncryptionKeyPair)(nil), // 8: types.EncryptionKeyPair + (*v1.Metadata)(nil), // 9: teleport.header.v1.Metadata +} +var file_teleport_recordingencryption_v1_recording_encryption_proto_depIdxs = []int32{ + 8, // 0: teleport.recordingencryption.v1.KeyPair.key_pair:type_name -> types.EncryptionKeyPair + 0, // 1: teleport.recordingencryption.v1.KeyPair.state:type_name -> teleport.recordingencryption.v1.KeyPairState + 1, // 2: teleport.recordingencryption.v1.RecordingEncryptionSpec.active_key_pairs:type_name -> teleport.recordingencryption.v1.KeyPair + 9, // 3: teleport.recordingencryption.v1.RecordingEncryption.metadata:type_name -> teleport.header.v1.Metadata + 2, // 4: teleport.recordingencryption.v1.RecordingEncryption.spec:type_name -> teleport.recordingencryption.v1.RecordingEncryptionSpec + 3, // 5: teleport.recordingencryption.v1.RecordingEncryption.status:type_name -> teleport.recordingencryption.v1.RecordingEncryptionStatus + 8, // 6: teleport.recordingencryption.v1.RotatedKeySpec.encryption_key_pair:type_name -> types.EncryptionKeyPair + 9, // 7: teleport.recordingencryption.v1.RotatedKey.metadata:type_name -> teleport.header.v1.Metadata + 5, // 8: teleport.recordingencryption.v1.RotatedKey.spec:type_name -> teleport.recordingencryption.v1.RotatedKeySpec + 6, // 9: teleport.recordingencryption.v1.RotatedKey.status:type_name -> teleport.recordingencryption.v1.RotatedKeyStatus + 10, // [10:10] is the sub-list for method output_type + 10, // [10:10] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name +} + +func init() { file_teleport_recordingencryption_v1_recording_encryption_proto_init() } +func file_teleport_recordingencryption_v1_recording_encryption_proto_init() { + if File_teleport_recordingencryption_v1_recording_encryption_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_teleport_recordingencryption_v1_recording_encryption_proto_rawDesc), len(file_teleport_recordingencryption_v1_recording_encryption_proto_rawDesc)), + NumEnums: 1, + NumMessages: 7, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_teleport_recordingencryption_v1_recording_encryption_proto_goTypes, + DependencyIndexes: file_teleport_recordingencryption_v1_recording_encryption_proto_depIdxs, + EnumInfos: file_teleport_recordingencryption_v1_recording_encryption_proto_enumTypes, + MessageInfos: file_teleport_recordingencryption_v1_recording_encryption_proto_msgTypes, + }.Build() + File_teleport_recordingencryption_v1_recording_encryption_proto = out.File + file_teleport_recordingencryption_v1_recording_encryption_proto_goTypes = nil + file_teleport_recordingencryption_v1_recording_encryption_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/recordingencryption/v1/recording_encryption_service.pb.go b/api/gen/proto/go/teleport/recordingencryption/v1/recording_encryption_service.pb.go new file mode 100644 index 0000000000000..1b0ca645dd6e9 --- /dev/null +++ b/api/gen/proto/go/teleport/recordingencryption/v1/recording_encryption_service.pb.go @@ -0,0 +1,980 @@ +// Copyright 2025 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc (unknown) +// source: teleport/recordingencryption/v1/recording_encryption_service.proto + +package recordingencryptionv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The handle to an upload for an encrypted session. +type Upload struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The primary identifier for an Upload. + UploadId string `protobuf:"bytes,1,opt,name=upload_id,json=uploadId,proto3" json:"upload_id,omitempty"` + // The session ID an upload is tied to. + SessionId string `protobuf:"bytes,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + // The time that an upload was created at. + InitiatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=initiated_at,json=initiatedAt,proto3" json:"initiated_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Upload) Reset() { + *x = Upload{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Upload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upload) ProtoMessage() {} + +func (x *Upload) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[0] + 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 Upload.ProtoReflect.Descriptor instead. +func (*Upload) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{0} +} + +func (x *Upload) GetUploadId() string { + if x != nil { + return x.UploadId + } + return "" +} + +func (x *Upload) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *Upload) GetInitiatedAt() *timestamppb.Timestamp { + if x != nil { + return x.InitiatedAt + } + return nil +} + +// The request to start a multipart upload for a specific session recording. +type CreateUploadRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The session ID associated with the recording being uploaded. + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateUploadRequest) Reset() { + *x = CreateUploadRequest{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateUploadRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUploadRequest) ProtoMessage() {} + +func (x *CreateUploadRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[1] + 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 CreateUploadRequest.ProtoReflect.Descriptor instead. +func (*CreateUploadRequest) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateUploadRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +// The resulting Upload message for a created Upload. +type CreateUploadResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The handle for the created Upload. + Upload *Upload `protobuf:"bytes,1,opt,name=upload,proto3" json:"upload,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateUploadResponse) Reset() { + *x = CreateUploadResponse{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateUploadResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUploadResponse) ProtoMessage() {} + +func (x *CreateUploadResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[2] + 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 CreateUploadResponse.ProtoReflect.Descriptor instead. +func (*CreateUploadResponse) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{2} +} + +func (x *CreateUploadResponse) GetUpload() *Upload { + if x != nil { + return x.Upload + } + return nil +} + +// The request to upload a single part in a multipart upload. +type UploadPartRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The handle to the in-progress upload that should be uploaded to. + Upload *Upload `protobuf:"bytes,1,opt,name=upload,proto3" json:"upload,omitempty"` + // The ordered index applied to the part. + PartNumber int64 `protobuf:"varint,2,opt,name=part_number,json=partNumber,proto3" json:"part_number,omitempty"` + // The encrypted part of session recording data being uploaded. + Part []byte `protobuf:"bytes,3,opt,name=part,proto3" json:"part,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UploadPartRequest) Reset() { + *x = UploadPartRequest{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UploadPartRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UploadPartRequest) ProtoMessage() {} + +func (x *UploadPartRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[3] + 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 UploadPartRequest.ProtoReflect.Descriptor instead. +func (*UploadPartRequest) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{3} +} + +func (x *UploadPartRequest) GetUpload() *Upload { + if x != nil { + return x.Upload + } + return nil +} + +func (x *UploadPartRequest) GetPartNumber() int64 { + if x != nil { + return x.PartNumber + } + return 0 +} + +func (x *UploadPartRequest) GetPart() []byte { + if x != nil { + return x.Part + } + return nil +} + +// The resulting metadata about an uploaded part. +type Part struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The ordered index applied to the part. + PartNumber int64 `protobuf:"varint,1,opt,name=part_number,json=partNumber,proto3" json:"part_number,omitempty"` + // The part e-tag value relevant to some storage backends. + Etag string `protobuf:"bytes,2,opt,name=etag,proto3" json:"etag,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Part) Reset() { + *x = Part{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Part) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Part) ProtoMessage() {} + +func (x *Part) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[4] + 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 Part.ProtoReflect.Descriptor instead. +func (*Part) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{4} +} + +func (x *Part) GetPartNumber() int64 { + if x != nil { + return x.PartNumber + } + return 0 +} + +func (x *Part) GetEtag() string { + if x != nil { + return x.Etag + } + return "" +} + +// A successfully uploaded Part to be included in the final CompleteUpload request. +type UploadPartResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The resulting part metadata about an uploaded part. + Part *Part `protobuf:"bytes,1,opt,name=part,proto3" json:"part,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UploadPartResponse) Reset() { + *x = UploadPartResponse{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UploadPartResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UploadPartResponse) ProtoMessage() {} + +func (x *UploadPartResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[5] + 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 UploadPartResponse.ProtoReflect.Descriptor instead. +func (*UploadPartResponse) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{5} +} + +func (x *UploadPartResponse) GetPart() *Part { + if x != nil { + return x.Part + } + return nil +} + +// The request to complete an upload. The included part numbers must match the parts successfully +// uploaded up until this point. +type CompleteUploadRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The handle to an upload to complete. + Upload *Upload `protobuf:"bytes,1,opt,name=upload,proto3" json:"upload,omitempty"` + // The parts expected to be successfully uploaded. + Parts []*Part `protobuf:"bytes,2,rep,name=parts,proto3" json:"parts,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CompleteUploadRequest) Reset() { + *x = CompleteUploadRequest{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CompleteUploadRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CompleteUploadRequest) ProtoMessage() {} + +func (x *CompleteUploadRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[6] + 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 CompleteUploadRequest.ProtoReflect.Descriptor instead. +func (*CompleteUploadRequest) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{6} +} + +func (x *CompleteUploadRequest) GetUpload() *Upload { + if x != nil { + return x.Upload + } + return nil +} + +func (x *CompleteUploadRequest) GetParts() []*Part { + if x != nil { + return x.Parts + } + return nil +} + +// The body of a CompleteUpload request. +type CompleteUploadResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CompleteUploadResponse) Reset() { + *x = CompleteUploadResponse{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CompleteUploadResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CompleteUploadResponse) ProtoMessage() {} + +func (x *CompleteUploadResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[7] + 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 CompleteUploadResponse.ProtoReflect.Descriptor instead. +func (*CompleteUploadResponse) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{7} +} + +// The body of a RotateKey request. +type RotateKeyRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RotateKeyRequest) Reset() { + *x = RotateKeyRequest{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RotateKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RotateKeyRequest) ProtoMessage() {} + +func (x *RotateKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[8] + 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 RotateKeyRequest.ProtoReflect.Descriptor instead. +func (*RotateKeyRequest) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{8} +} + +// The return value of a RotateKey request. +type RotateKeyResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RotateKeyResponse) Reset() { + *x = RotateKeyResponse{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RotateKeyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RotateKeyResponse) ProtoMessage() {} + +func (x *RotateKeyResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[9] + 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 RotateKeyResponse.ProtoReflect.Descriptor instead. +func (*RotateKeyResponse) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{9} +} + +// The body of a GetRotationState request. +type GetRotationStateRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + PageSize int32 `protobuf:"varint,1,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + PageToken string `protobuf:"bytes,2,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetRotationStateRequest) Reset() { + *x = GetRotationStateRequest{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetRotationStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRotationStateRequest) ProtoMessage() {} + +func (x *GetRotationStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[10] + 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 GetRotationStateRequest.ProtoReflect.Descriptor instead. +func (*GetRotationStateRequest) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{10} +} + +func (x *GetRotationStateRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *GetRotationStateRequest) GetPageToken() string { + if x != nil { + return x.PageToken + } + return "" +} + +// A public key fingerprint coupled with its current state. +type FingerprintWithState struct { + state protoimpl.MessageState `protogen:"open.v1"` + // A fingerprint identifying the public key of a KeyPair. + Fingerprint string `protobuf:"bytes,1,opt,name=fingerprint,proto3" json:"fingerprint,omitempty"` + // The state associated with the identified KeyPair. + State KeyPairState `protobuf:"varint,2,opt,name=state,proto3,enum=teleport.recordingencryption.v1.KeyPairState" json:"state,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FingerprintWithState) Reset() { + *x = FingerprintWithState{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FingerprintWithState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FingerprintWithState) ProtoMessage() {} + +func (x *FingerprintWithState) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[11] + 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 FingerprintWithState.ProtoReflect.Descriptor instead. +func (*FingerprintWithState) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{11} +} + +func (x *FingerprintWithState) GetFingerprint() string { + if x != nil { + return x.Fingerprint + } + return "" +} + +func (x *FingerprintWithState) GetState() KeyPairState { + if x != nil { + return x.State + } + return KeyPairState_KEY_PAIR_STATE_UNSPECIFIED +} + +// The current state of all active encryption key pairs. +type GetRotationStateResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + NextPageToken string `protobuf:"bytes,1,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` + // The state of all active encryption key pairs. + KeyPairStates []*FingerprintWithState `protobuf:"bytes,2,rep,name=key_pair_states,json=keyPairStates,proto3" json:"key_pair_states,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetRotationStateResponse) Reset() { + *x = GetRotationStateResponse{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetRotationStateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetRotationStateResponse) ProtoMessage() {} + +func (x *GetRotationStateResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[12] + 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 GetRotationStateResponse.ProtoReflect.Descriptor instead. +func (*GetRotationStateResponse) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{12} +} + +func (x *GetRotationStateResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +func (x *GetRotationStateResponse) GetKeyPairStates() []*FingerprintWithState { + if x != nil { + return x.KeyPairStates + } + return nil +} + +// The body of a CompleteRotation request. +type CompleteRotationRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CompleteRotationRequest) Reset() { + *x = CompleteRotationRequest{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CompleteRotationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CompleteRotationRequest) ProtoMessage() {} + +func (x *CompleteRotationRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[13] + 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 CompleteRotationRequest.ProtoReflect.Descriptor instead. +func (*CompleteRotationRequest) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{13} +} + +// The return value of a CompleteRotation request. +type CompleteRotationResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CompleteRotationResponse) Reset() { + *x = CompleteRotationResponse{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CompleteRotationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CompleteRotationResponse) ProtoMessage() {} + +func (x *CompleteRotationResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[14] + 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 CompleteRotationResponse.ProtoReflect.Descriptor instead. +func (*CompleteRotationResponse) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{14} +} + +// The body of a RollbackRotation request. +type RollbackRotationRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RollbackRotationRequest) Reset() { + *x = RollbackRotationRequest{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RollbackRotationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RollbackRotationRequest) ProtoMessage() {} + +func (x *RollbackRotationRequest) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[15] + 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 RollbackRotationRequest.ProtoReflect.Descriptor instead. +func (*RollbackRotationRequest) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{15} +} + +// The return value of a RollbackRotation request +type RollbackRotationResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RollbackRotationResponse) Reset() { + *x = RollbackRotationResponse{} + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RollbackRotationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RollbackRotationResponse) ProtoMessage() {} + +func (x *RollbackRotationResponse) ProtoReflect() protoreflect.Message { + mi := &file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes[16] + 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 RollbackRotationResponse.ProtoReflect.Descriptor instead. +func (*RollbackRotationResponse) Descriptor() ([]byte, []int) { + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP(), []int{16} +} + +var File_teleport_recordingencryption_v1_recording_encryption_service_proto protoreflect.FileDescriptor + +const file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDesc = "" + + "\n" + + "Bteleport/recordingencryption/v1/recording_encryption_service.proto\x12\x1fteleport.recordingencryption.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a:teleport/recordingencryption/v1/recording_encryption.proto\"\x83\x01\n" + + "\x06Upload\x12\x1b\n" + + "\tupload_id\x18\x01 \x01(\tR\buploadId\x12\x1d\n" + + "\n" + + "session_id\x18\x02 \x01(\tR\tsessionId\x12=\n" + + "\finitiated_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\vinitiatedAt\"4\n" + + "\x13CreateUploadRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\"W\n" + + "\x14CreateUploadResponse\x12?\n" + + "\x06upload\x18\x01 \x01(\v2'.teleport.recordingencryption.v1.UploadR\x06upload\"\x89\x01\n" + + "\x11UploadPartRequest\x12?\n" + + "\x06upload\x18\x01 \x01(\v2'.teleport.recordingencryption.v1.UploadR\x06upload\x12\x1f\n" + + "\vpart_number\x18\x02 \x01(\x03R\n" + + "partNumber\x12\x12\n" + + "\x04part\x18\x03 \x01(\fR\x04part\";\n" + + "\x04Part\x12\x1f\n" + + "\vpart_number\x18\x01 \x01(\x03R\n" + + "partNumber\x12\x12\n" + + "\x04etag\x18\x02 \x01(\tR\x04etag\"O\n" + + "\x12UploadPartResponse\x129\n" + + "\x04part\x18\x01 \x01(\v2%.teleport.recordingencryption.v1.PartR\x04part\"\x95\x01\n" + + "\x15CompleteUploadRequest\x12?\n" + + "\x06upload\x18\x01 \x01(\v2'.teleport.recordingencryption.v1.UploadR\x06upload\x12;\n" + + "\x05parts\x18\x02 \x03(\v2%.teleport.recordingencryption.v1.PartR\x05parts\"\x18\n" + + "\x16CompleteUploadResponse\"\x12\n" + + "\x10RotateKeyRequest\"\x13\n" + + "\x11RotateKeyResponse\"U\n" + + "\x17GetRotationStateRequest\x12\x1b\n" + + "\tpage_size\x18\x01 \x01(\x05R\bpageSize\x12\x1d\n" + + "\n" + + "page_token\x18\x02 \x01(\tR\tpageToken\"}\n" + + "\x14FingerprintWithState\x12 \n" + + "\vfingerprint\x18\x01 \x01(\tR\vfingerprint\x12C\n" + + "\x05state\x18\x02 \x01(\x0e2-.teleport.recordingencryption.v1.KeyPairStateR\x05state\"\xa1\x01\n" + + "\x18GetRotationStateResponse\x12&\n" + + "\x0fnext_page_token\x18\x01 \x01(\tR\rnextPageToken\x12]\n" + + "\x0fkey_pair_states\x18\x02 \x03(\v25.teleport.recordingencryption.v1.FingerprintWithStateR\rkeyPairStates\"\x19\n" + + "\x17CompleteRotationRequest\"\x1a\n" + + "\x18CompleteRotationResponse\"\x19\n" + + "\x17RollbackRotationRequest\"\x1a\n" + + "\x18RollbackRotationResponse2\xa6\a\n" + + "\x1aRecordingEncryptionService\x12{\n" + + "\fCreateUpload\x124.teleport.recordingencryption.v1.CreateUploadRequest\x1a5.teleport.recordingencryption.v1.CreateUploadResponse\x12u\n" + + "\n" + + "UploadPart\x122.teleport.recordingencryption.v1.UploadPartRequest\x1a3.teleport.recordingencryption.v1.UploadPartResponse\x12\x81\x01\n" + + "\x0eCompleteUpload\x126.teleport.recordingencryption.v1.CompleteUploadRequest\x1a7.teleport.recordingencryption.v1.CompleteUploadResponse\x12r\n" + + "\tRotateKey\x121.teleport.recordingencryption.v1.RotateKeyRequest\x1a2.teleport.recordingencryption.v1.RotateKeyResponse\x12\x87\x01\n" + + "\x10GetRotationState\x128.teleport.recordingencryption.v1.GetRotationStateRequest\x1a9.teleport.recordingencryption.v1.GetRotationStateResponse\x12\x87\x01\n" + + "\x10CompleteRotation\x128.teleport.recordingencryption.v1.CompleteRotationRequest\x1a9.teleport.recordingencryption.v1.CompleteRotationResponse\x12\x87\x01\n" + + "\x10RollbackRotation\x128.teleport.recordingencryption.v1.RollbackRotationRequest\x1a9.teleport.recordingencryption.v1.RollbackRotationResponseBjZhgithub.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1;recordingencryptionv1b\x06proto3" + +var ( + file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescOnce sync.Once + file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescData []byte +) + +func file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescGZIP() []byte { + file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescOnce.Do(func() { + file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDesc), len(file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDesc))) + }) + return file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDescData +} + +var file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_teleport_recordingencryption_v1_recording_encryption_service_proto_goTypes = []any{ + (*Upload)(nil), // 0: teleport.recordingencryption.v1.Upload + (*CreateUploadRequest)(nil), // 1: teleport.recordingencryption.v1.CreateUploadRequest + (*CreateUploadResponse)(nil), // 2: teleport.recordingencryption.v1.CreateUploadResponse + (*UploadPartRequest)(nil), // 3: teleport.recordingencryption.v1.UploadPartRequest + (*Part)(nil), // 4: teleport.recordingencryption.v1.Part + (*UploadPartResponse)(nil), // 5: teleport.recordingencryption.v1.UploadPartResponse + (*CompleteUploadRequest)(nil), // 6: teleport.recordingencryption.v1.CompleteUploadRequest + (*CompleteUploadResponse)(nil), // 7: teleport.recordingencryption.v1.CompleteUploadResponse + (*RotateKeyRequest)(nil), // 8: teleport.recordingencryption.v1.RotateKeyRequest + (*RotateKeyResponse)(nil), // 9: teleport.recordingencryption.v1.RotateKeyResponse + (*GetRotationStateRequest)(nil), // 10: teleport.recordingencryption.v1.GetRotationStateRequest + (*FingerprintWithState)(nil), // 11: teleport.recordingencryption.v1.FingerprintWithState + (*GetRotationStateResponse)(nil), // 12: teleport.recordingencryption.v1.GetRotationStateResponse + (*CompleteRotationRequest)(nil), // 13: teleport.recordingencryption.v1.CompleteRotationRequest + (*CompleteRotationResponse)(nil), // 14: teleport.recordingencryption.v1.CompleteRotationResponse + (*RollbackRotationRequest)(nil), // 15: teleport.recordingencryption.v1.RollbackRotationRequest + (*RollbackRotationResponse)(nil), // 16: teleport.recordingencryption.v1.RollbackRotationResponse + (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp + (KeyPairState)(0), // 18: teleport.recordingencryption.v1.KeyPairState +} +var file_teleport_recordingencryption_v1_recording_encryption_service_proto_depIdxs = []int32{ + 17, // 0: teleport.recordingencryption.v1.Upload.initiated_at:type_name -> google.protobuf.Timestamp + 0, // 1: teleport.recordingencryption.v1.CreateUploadResponse.upload:type_name -> teleport.recordingencryption.v1.Upload + 0, // 2: teleport.recordingencryption.v1.UploadPartRequest.upload:type_name -> teleport.recordingencryption.v1.Upload + 4, // 3: teleport.recordingencryption.v1.UploadPartResponse.part:type_name -> teleport.recordingencryption.v1.Part + 0, // 4: teleport.recordingencryption.v1.CompleteUploadRequest.upload:type_name -> teleport.recordingencryption.v1.Upload + 4, // 5: teleport.recordingencryption.v1.CompleteUploadRequest.parts:type_name -> teleport.recordingencryption.v1.Part + 18, // 6: teleport.recordingencryption.v1.FingerprintWithState.state:type_name -> teleport.recordingencryption.v1.KeyPairState + 11, // 7: teleport.recordingencryption.v1.GetRotationStateResponse.key_pair_states:type_name -> teleport.recordingencryption.v1.FingerprintWithState + 1, // 8: teleport.recordingencryption.v1.RecordingEncryptionService.CreateUpload:input_type -> teleport.recordingencryption.v1.CreateUploadRequest + 3, // 9: teleport.recordingencryption.v1.RecordingEncryptionService.UploadPart:input_type -> teleport.recordingencryption.v1.UploadPartRequest + 6, // 10: teleport.recordingencryption.v1.RecordingEncryptionService.CompleteUpload:input_type -> teleport.recordingencryption.v1.CompleteUploadRequest + 8, // 11: teleport.recordingencryption.v1.RecordingEncryptionService.RotateKey:input_type -> teleport.recordingencryption.v1.RotateKeyRequest + 10, // 12: teleport.recordingencryption.v1.RecordingEncryptionService.GetRotationState:input_type -> teleport.recordingencryption.v1.GetRotationStateRequest + 13, // 13: teleport.recordingencryption.v1.RecordingEncryptionService.CompleteRotation:input_type -> teleport.recordingencryption.v1.CompleteRotationRequest + 15, // 14: teleport.recordingencryption.v1.RecordingEncryptionService.RollbackRotation:input_type -> teleport.recordingencryption.v1.RollbackRotationRequest + 2, // 15: teleport.recordingencryption.v1.RecordingEncryptionService.CreateUpload:output_type -> teleport.recordingencryption.v1.CreateUploadResponse + 5, // 16: teleport.recordingencryption.v1.RecordingEncryptionService.UploadPart:output_type -> teleport.recordingencryption.v1.UploadPartResponse + 7, // 17: teleport.recordingencryption.v1.RecordingEncryptionService.CompleteUpload:output_type -> teleport.recordingencryption.v1.CompleteUploadResponse + 9, // 18: teleport.recordingencryption.v1.RecordingEncryptionService.RotateKey:output_type -> teleport.recordingencryption.v1.RotateKeyResponse + 12, // 19: teleport.recordingencryption.v1.RecordingEncryptionService.GetRotationState:output_type -> teleport.recordingencryption.v1.GetRotationStateResponse + 14, // 20: teleport.recordingencryption.v1.RecordingEncryptionService.CompleteRotation:output_type -> teleport.recordingencryption.v1.CompleteRotationResponse + 16, // 21: teleport.recordingencryption.v1.RecordingEncryptionService.RollbackRotation:output_type -> teleport.recordingencryption.v1.RollbackRotationResponse + 15, // [15:22] is the sub-list for method output_type + 8, // [8:15] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_teleport_recordingencryption_v1_recording_encryption_service_proto_init() } +func file_teleport_recordingencryption_v1_recording_encryption_service_proto_init() { + if File_teleport_recordingencryption_v1_recording_encryption_service_proto != nil { + return + } + file_teleport_recordingencryption_v1_recording_encryption_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDesc), len(file_teleport_recordingencryption_v1_recording_encryption_service_proto_rawDesc)), + NumEnums: 0, + NumMessages: 17, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_teleport_recordingencryption_v1_recording_encryption_service_proto_goTypes, + DependencyIndexes: file_teleport_recordingencryption_v1_recording_encryption_service_proto_depIdxs, + MessageInfos: file_teleport_recordingencryption_v1_recording_encryption_service_proto_msgTypes, + }.Build() + File_teleport_recordingencryption_v1_recording_encryption_service_proto = out.File + file_teleport_recordingencryption_v1_recording_encryption_service_proto_goTypes = nil + file_teleport_recordingencryption_v1_recording_encryption_service_proto_depIdxs = nil +} diff --git a/api/gen/proto/go/teleport/recordingencryption/v1/recording_encryption_service_grpc.pb.go b/api/gen/proto/go/teleport/recordingencryption/v1/recording_encryption_service_grpc.pb.go new file mode 100644 index 0000000000000..2227d21eea726 --- /dev/null +++ b/api/gen/proto/go/teleport/recordingencryption/v1/recording_encryption_service_grpc.pb.go @@ -0,0 +1,384 @@ +// Copyright 2025 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc (unknown) +// source: teleport/recordingencryption/v1/recording_encryption_service.proto + +package recordingencryptionv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + RecordingEncryptionService_CreateUpload_FullMethodName = "/teleport.recordingencryption.v1.RecordingEncryptionService/CreateUpload" + RecordingEncryptionService_UploadPart_FullMethodName = "/teleport.recordingencryption.v1.RecordingEncryptionService/UploadPart" + RecordingEncryptionService_CompleteUpload_FullMethodName = "/teleport.recordingencryption.v1.RecordingEncryptionService/CompleteUpload" + RecordingEncryptionService_RotateKey_FullMethodName = "/teleport.recordingencryption.v1.RecordingEncryptionService/RotateKey" + RecordingEncryptionService_GetRotationState_FullMethodName = "/teleport.recordingencryption.v1.RecordingEncryptionService/GetRotationState" + RecordingEncryptionService_CompleteRotation_FullMethodName = "/teleport.recordingencryption.v1.RecordingEncryptionService/CompleteRotation" + RecordingEncryptionService_RollbackRotation_FullMethodName = "/teleport.recordingencryption.v1.RecordingEncryptionService/RollbackRotation" +) + +// RecordingEncryptionServiceClient is the client API for RecordingEncryptionService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// RecordingEncryption provides methods to manage cluster encryption configuration resources. +type RecordingEncryptionServiceClient interface { + // CreateUpload begins a multipart upload for an encrypted recording. The + // returned upload ID should be used while uploading parts. + CreateUpload(ctx context.Context, in *CreateUploadRequest, opts ...grpc.CallOption) (*CreateUploadResponse, error) + // UploadPart uploads a part to the given upload ID. + UploadPart(ctx context.Context, in *UploadPartRequest, opts ...grpc.CallOption) (*UploadPartResponse, error) + // CompleteUploadRequest marks a multipart upload as complete. + CompleteUpload(ctx context.Context, in *CompleteUploadRequest, opts ...grpc.CallOption) (*CompleteUploadResponse, error) + // RotateKey rotates the key pair used for encrypting session recording data. + RotateKey(ctx context.Context, in *RotateKeyRequest, opts ...grpc.CallOption) (*RotateKeyResponse, error) + // GetRotationState returns whether or not a rotation is in progress. + GetRotationState(ctx context.Context, in *GetRotationStateRequest, opts ...grpc.CallOption) (*GetRotationStateResponse, error) + // CompleteRotation moves rotated keys out of the active set. + CompleteRotation(ctx context.Context, in *CompleteRotationRequest, opts ...grpc.CallOption) (*CompleteRotationResponse, error) + // RollbackRotation removes active keys and reverts rotating keys back to being active. + RollbackRotation(ctx context.Context, in *RollbackRotationRequest, opts ...grpc.CallOption) (*RollbackRotationResponse, error) +} + +type recordingEncryptionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewRecordingEncryptionServiceClient(cc grpc.ClientConnInterface) RecordingEncryptionServiceClient { + return &recordingEncryptionServiceClient{cc} +} + +func (c *recordingEncryptionServiceClient) CreateUpload(ctx context.Context, in *CreateUploadRequest, opts ...grpc.CallOption) (*CreateUploadResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateUploadResponse) + err := c.cc.Invoke(ctx, RecordingEncryptionService_CreateUpload_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *recordingEncryptionServiceClient) UploadPart(ctx context.Context, in *UploadPartRequest, opts ...grpc.CallOption) (*UploadPartResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UploadPartResponse) + err := c.cc.Invoke(ctx, RecordingEncryptionService_UploadPart_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *recordingEncryptionServiceClient) CompleteUpload(ctx context.Context, in *CompleteUploadRequest, opts ...grpc.CallOption) (*CompleteUploadResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CompleteUploadResponse) + err := c.cc.Invoke(ctx, RecordingEncryptionService_CompleteUpload_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *recordingEncryptionServiceClient) RotateKey(ctx context.Context, in *RotateKeyRequest, opts ...grpc.CallOption) (*RotateKeyResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RotateKeyResponse) + err := c.cc.Invoke(ctx, RecordingEncryptionService_RotateKey_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *recordingEncryptionServiceClient) GetRotationState(ctx context.Context, in *GetRotationStateRequest, opts ...grpc.CallOption) (*GetRotationStateResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetRotationStateResponse) + err := c.cc.Invoke(ctx, RecordingEncryptionService_GetRotationState_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *recordingEncryptionServiceClient) CompleteRotation(ctx context.Context, in *CompleteRotationRequest, opts ...grpc.CallOption) (*CompleteRotationResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CompleteRotationResponse) + err := c.cc.Invoke(ctx, RecordingEncryptionService_CompleteRotation_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *recordingEncryptionServiceClient) RollbackRotation(ctx context.Context, in *RollbackRotationRequest, opts ...grpc.CallOption) (*RollbackRotationResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RollbackRotationResponse) + err := c.cc.Invoke(ctx, RecordingEncryptionService_RollbackRotation_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// RecordingEncryptionServiceServer is the server API for RecordingEncryptionService service. +// All implementations must embed UnimplementedRecordingEncryptionServiceServer +// for forward compatibility. +// +// RecordingEncryption provides methods to manage cluster encryption configuration resources. +type RecordingEncryptionServiceServer interface { + // CreateUpload begins a multipart upload for an encrypted recording. The + // returned upload ID should be used while uploading parts. + CreateUpload(context.Context, *CreateUploadRequest) (*CreateUploadResponse, error) + // UploadPart uploads a part to the given upload ID. + UploadPart(context.Context, *UploadPartRequest) (*UploadPartResponse, error) + // CompleteUploadRequest marks a multipart upload as complete. + CompleteUpload(context.Context, *CompleteUploadRequest) (*CompleteUploadResponse, error) + // RotateKey rotates the key pair used for encrypting session recording data. + RotateKey(context.Context, *RotateKeyRequest) (*RotateKeyResponse, error) + // GetRotationState returns whether or not a rotation is in progress. + GetRotationState(context.Context, *GetRotationStateRequest) (*GetRotationStateResponse, error) + // CompleteRotation moves rotated keys out of the active set. + CompleteRotation(context.Context, *CompleteRotationRequest) (*CompleteRotationResponse, error) + // RollbackRotation removes active keys and reverts rotating keys back to being active. + RollbackRotation(context.Context, *RollbackRotationRequest) (*RollbackRotationResponse, error) + mustEmbedUnimplementedRecordingEncryptionServiceServer() +} + +// UnimplementedRecordingEncryptionServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedRecordingEncryptionServiceServer struct{} + +func (UnimplementedRecordingEncryptionServiceServer) CreateUpload(context.Context, *CreateUploadRequest) (*CreateUploadResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateUpload not implemented") +} +func (UnimplementedRecordingEncryptionServiceServer) UploadPart(context.Context, *UploadPartRequest) (*UploadPartResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UploadPart not implemented") +} +func (UnimplementedRecordingEncryptionServiceServer) CompleteUpload(context.Context, *CompleteUploadRequest) (*CompleteUploadResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CompleteUpload not implemented") +} +func (UnimplementedRecordingEncryptionServiceServer) RotateKey(context.Context, *RotateKeyRequest) (*RotateKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RotateKey not implemented") +} +func (UnimplementedRecordingEncryptionServiceServer) GetRotationState(context.Context, *GetRotationStateRequest) (*GetRotationStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRotationState not implemented") +} +func (UnimplementedRecordingEncryptionServiceServer) CompleteRotation(context.Context, *CompleteRotationRequest) (*CompleteRotationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CompleteRotation not implemented") +} +func (UnimplementedRecordingEncryptionServiceServer) RollbackRotation(context.Context, *RollbackRotationRequest) (*RollbackRotationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RollbackRotation not implemented") +} +func (UnimplementedRecordingEncryptionServiceServer) mustEmbedUnimplementedRecordingEncryptionServiceServer() { +} +func (UnimplementedRecordingEncryptionServiceServer) testEmbeddedByValue() {} + +// UnsafeRecordingEncryptionServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to RecordingEncryptionServiceServer will +// result in compilation errors. +type UnsafeRecordingEncryptionServiceServer interface { + mustEmbedUnimplementedRecordingEncryptionServiceServer() +} + +func RegisterRecordingEncryptionServiceServer(s grpc.ServiceRegistrar, srv RecordingEncryptionServiceServer) { + // If the following call pancis, it indicates UnimplementedRecordingEncryptionServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&RecordingEncryptionService_ServiceDesc, srv) +} + +func _RecordingEncryptionService_CreateUpload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateUploadRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RecordingEncryptionServiceServer).CreateUpload(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RecordingEncryptionService_CreateUpload_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RecordingEncryptionServiceServer).CreateUpload(ctx, req.(*CreateUploadRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RecordingEncryptionService_UploadPart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UploadPartRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RecordingEncryptionServiceServer).UploadPart(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RecordingEncryptionService_UploadPart_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RecordingEncryptionServiceServer).UploadPart(ctx, req.(*UploadPartRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RecordingEncryptionService_CompleteUpload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CompleteUploadRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RecordingEncryptionServiceServer).CompleteUpload(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RecordingEncryptionService_CompleteUpload_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RecordingEncryptionServiceServer).CompleteUpload(ctx, req.(*CompleteUploadRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RecordingEncryptionService_RotateKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RotateKeyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RecordingEncryptionServiceServer).RotateKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RecordingEncryptionService_RotateKey_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RecordingEncryptionServiceServer).RotateKey(ctx, req.(*RotateKeyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RecordingEncryptionService_GetRotationState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetRotationStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RecordingEncryptionServiceServer).GetRotationState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RecordingEncryptionService_GetRotationState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RecordingEncryptionServiceServer).GetRotationState(ctx, req.(*GetRotationStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RecordingEncryptionService_CompleteRotation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CompleteRotationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RecordingEncryptionServiceServer).CompleteRotation(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RecordingEncryptionService_CompleteRotation_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RecordingEncryptionServiceServer).CompleteRotation(ctx, req.(*CompleteRotationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RecordingEncryptionService_RollbackRotation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RollbackRotationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RecordingEncryptionServiceServer).RollbackRotation(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RecordingEncryptionService_RollbackRotation_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RecordingEncryptionServiceServer).RollbackRotation(ctx, req.(*RollbackRotationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// RecordingEncryptionService_ServiceDesc is the grpc.ServiceDesc for RecordingEncryptionService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var RecordingEncryptionService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "teleport.recordingencryption.v1.RecordingEncryptionService", + HandlerType: (*RecordingEncryptionServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateUpload", + Handler: _RecordingEncryptionService_CreateUpload_Handler, + }, + { + MethodName: "UploadPart", + Handler: _RecordingEncryptionService_UploadPart_Handler, + }, + { + MethodName: "CompleteUpload", + Handler: _RecordingEncryptionService_CompleteUpload_Handler, + }, + { + MethodName: "RotateKey", + Handler: _RecordingEncryptionService_RotateKey_Handler, + }, + { + MethodName: "GetRotationState", + Handler: _RecordingEncryptionService_GetRotationState_Handler, + }, + { + MethodName: "CompleteRotation", + Handler: _RecordingEncryptionService_CompleteRotation_Handler, + }, + { + MethodName: "RollbackRotation", + Handler: _RecordingEncryptionService_RollbackRotation_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "teleport/recordingencryption/v1/recording_encryption_service.proto", +} diff --git a/api/proto/teleport/legacy/client/proto/event.proto b/api/proto/teleport/legacy/client/proto/event.proto index 4f3b2350420d9..8d9caee246b37 100644 --- a/api/proto/teleport/legacy/client/proto/event.proto +++ b/api/proto/teleport/legacy/client/proto/event.proto @@ -31,6 +31,7 @@ import "teleport/machineid/v1/bot_instance.proto"; import "teleport/machineid/v1/federation.proto"; import "teleport/notifications/v1/notifications.proto"; import "teleport/provisioning/v1/provisioning.proto"; +import "teleport/recordingencryption/v1/recording_encryption.proto"; import "teleport/scopes/access/v1/assignment.proto"; import "teleport/scopes/access/v1/role.proto"; import "teleport/secreports/v1/secreports.proto"; @@ -225,6 +226,8 @@ message Event { teleport.scopes.access.v1.ScopedRole ScopedRole = 80; // ScopedRoleAssignment is an assignment of one or more scoped roles to a user. teleport.scopes.access.v1.ScopedRoleAssignment ScopedRoleAssignment = 81; + // RecordingEncryption is a resource for controlling session recording encryption. + teleport.recordingencryption.v1.RecordingEncryption RecordingEncryption = 83; // PluginV1 is a resource for Teleport plugins. types.PluginV1 plugin = 84; } diff --git a/api/proto/teleport/legacy/types/types.proto b/api/proto/teleport/legacy/types/types.proto index 507c339d3117c..1e1e461c0bac2 100644 --- a/api/proto/teleport/legacy/types/types.proto +++ b/api/proto/teleport/legacy/types/types.proto @@ -1267,6 +1267,25 @@ message JWTKeyPair { PrivateKeyType PrivateKeyType = 3 [(gogoproto.jsontag) = "private_key_type,omitempty"]; } +// EncryptionKeyPair is a PKIX ASN.1 DER encoded keypair used for encrypting and decrypting data. +message EncryptionKeyPair { + // PublicKey is a PKIX ASN.1 DER encoded public key. + bytes public_key = 1 [(gogoproto.jsontag) = "public_key,omitempty"]; + // PrivateKey is a PKCS#8 ASN.1 DER encoded private key. + bytes private_key = 2 [(gogoproto.jsontag) = "private_key,omitempty"]; + // PrivateKeyType is the type of the PrivateKey. + PrivateKeyType private_key_type = 3 [(gogoproto.jsontag) = "private_key_type,omitempty"]; + // Hash function used during OAEP encryption/decryption. It maps directly to the possible + // values of [crypto.Hash] in the go crypto package. + uint32 hash = 4 [(gogoproto.jsontag) = "hash,omitempty"]; +} + +// A public key to be used as a recipient during age encryption of session recordings. +message AgeEncryptionKey { + // A PKIX ASN.1 DER encoded public key used for key wrapping during age encryption. Expected to be RSA 4096. + bytes public_key = 1 [(gogoproto.jsontag) = "public_key"]; +} + // CertAuthorityV2 is version 2 resource spec for Cert Authority message CertAuthorityV2 { option (gogoproto.goproto_stringer) = false; @@ -2427,6 +2446,41 @@ message SessionRecordingConfigV2 { (gogoproto.nullable) = false, (gogoproto.jsontag) = "spec" ]; + // Status is the SessionRecordingConfig status containing active encryption keys + SessionRecordingConfigStatus Status = 6 [ + (gogoproto.nullable) = true, + (gogoproto.jsontag) = "status,omitempty" + ]; +} + +// KeyLabel combines a label that can be used to identify one or more keys with a keystore type that +// determines where the keys can be found. +message KeyLabel { + // Type represents which keystore should be searched when looking up keys by label. + string type = 1 [(gogoproto.jsontag) = "type"]; + // Label is a value that can be used with the related keystore in order to find relevant keys. + string label = 2 [(gogoproto.jsontag) = "label"]; +} + +// ManualKeyManagementConfig defines whether or not recording encryption keys should be managed externally +// and how to query those keys. +message ManualKeyManagementConfig { + // Enabled controls whether or recording encryption keys should be managed externally. + bool enabled = 1 [(gogoproto.jsontag) = "enabled,omitempty"]; + // ActiveKeys describe which keys should be queried for active recording encryption and replay. + repeated KeyLabel active_keys = 2 [(gogoproto.jsontag) = "active_keys,omitempty"]; + // RotatedKeys describe which keys should be queried for historical replay. + repeated KeyLabel rotated_keys = 3 [(gogoproto.jsontag) = "rotated_keys,omitempty"]; +} + +// SessionRecordingEncryptionConfig configures if and how session recordings +// should be encrypted. +message SessionRecordingEncryptionConfig { + // Enabled controls whether or not session recordings should be encrypted. + bool enabled = 1 [(gogoproto.jsontag) = "enabled,omitempty"]; + // ManualKeyManagement defines whether or not recording encryption keys should be managed externally + // and how to query those keys. + ManualKeyManagementConfig manual_key_management = 2 [(gogoproto.jsontag) = "manual_key_management,omitempty"]; } // SessionRecordingConfigSpecV2 is the actual data we care about @@ -2442,6 +2496,20 @@ message SessionRecordingConfigSpecV2 { (gogoproto.jsontag) = "proxy_checks_host_keys", (gogoproto.customtype) = "BoolOption" ]; + + // Encryption configures if and how session recordings should be encrypted. + SessionRecordingEncryptionConfig encryption = 3 [ + (gogoproto.nullable) = true, + (gogoproto.jsontag) = "encryption,omitempty" + ]; +} + +// SessionRecordingConfigStatus contains the currently active age encryption keys used +// for encrypted session recording. +message SessionRecordingConfigStatus { + // EncryptionKeys contain the currently active age encryption keys used for + // encrypted session recording. + repeated AgeEncryptionKey encryption_keys = 1 [(gogoproto.jsontag) = "encryption_keys"]; } // AuthPreferenceV2 implements the AuthPreference interface. diff --git a/api/proto/teleport/recordingencryption/v1/recording_encryption.proto b/api/proto/teleport/recordingencryption/v1/recording_encryption.proto new file mode 100644 index 0000000000000..e8addac57d980 --- /dev/null +++ b/api/proto/teleport/recordingencryption/v1/recording_encryption.proto @@ -0,0 +1,91 @@ +// Copyright 2025 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.recordingencryption.v1; + +import "teleport/header/v1/metadata.proto"; +import "teleport/legacy/types/types.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1;recordingencryptionv1"; + +// The possible states a KeyPair can be in. +enum KeyPairState { + // Unspecified value + KEY_PAIR_STATE_UNSPECIFIED = 0; + // Represents an active key. + KEY_PAIR_STATE_ACTIVE = 1; + // Represents a key in the process of being rotated. + KEY_PAIR_STATE_ROTATING = 2; + // Represents a key being rotated in that is inaccessible to at least one + // auth server. + KEY_PAIR_STATE_INACCESSIBLE = 3; +} + +// A key pair used with age to wrap and unwrap file keys for session recording encryption. +message KeyPair { + // A key pair used with age to wrap and unwrap file keys for session recording encryption. + types.EncryptionKeyPair key_pair = 1; + // The current state of the key pair. + KeyPairState state = 2; +} + +// RecordingEncryptionSpec contains the active key set for encrypted session recording. +message RecordingEncryptionSpec { + reserved 1; // active_keys + reserved "active_keys"; + + // A list of active key pairs used for session recording encryption. The unique set of + // active public keys are used as recipients during age encryption. This allows any + // active private key to be used during decryption which guards against recordings being + // inaccessible to auth servers waiting for key rotation. + repeated KeyPair active_key_pairs = 2; +} + +// RecordingEncryptionStatus contains the status of the RecordingEncryption resource. +message RecordingEncryptionStatus {} + +// RecordingEncryption contains cluster state for encrypted session recordings. +message RecordingEncryption { + string kind = 1; + string sub_kind = 2; + string version = 3; + teleport.header.v1.Metadata metadata = 4; + RecordingEncryptionSpec spec = 5; + RecordingEncryptionStatus status = 6; +} + +// A rotated key pair previously used with age to wrap and unwrap file keys for session recording +// encryption. +message RotatedKeySpec { + // The rotated key pair previously used with age to wrap and unwrap file keys for session recording + // encryption. + types.EncryptionKeyPair encryption_key_pair = 2; +} + +// The empty status of a RotatedKey. +message RotatedKeyStatus {} + +// A previously rotated encryption key for session recordings kept for future replay. The metadata.name +// is expected to be the fingerprint of the public key contained in the spec, which is a hex encoded +// SHA256 hash of its PKIX form. +message RotatedKey { + string kind = 1; + string sub_kind = 2; + string version = 3; + teleport.header.v1.Metadata metadata = 4; + RotatedKeySpec spec = 5; + RotatedKeyStatus status = 6; +} diff --git a/api/proto/teleport/recordingencryption/v1/recording_encryption_service.proto b/api/proto/teleport/recordingencryption/v1/recording_encryption_service.proto new file mode 100644 index 0000000000000..130eb2eba0144 --- /dev/null +++ b/api/proto/teleport/recordingencryption/v1/recording_encryption_service.proto @@ -0,0 +1,139 @@ +// Copyright 2025 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package teleport.recordingencryption.v1; + +import "google/protobuf/timestamp.proto"; +import "teleport/recordingencryption/v1/recording_encryption.proto"; + +option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1;recordingencryptionv1"; + +// RecordingEncryption provides methods to manage cluster encryption configuration resources. +service RecordingEncryptionService { + // CreateUpload begins a multipart upload for an encrypted recording. The + // returned upload ID should be used while uploading parts. + rpc CreateUpload(CreateUploadRequest) returns (CreateUploadResponse); + // UploadPart uploads a part to the given upload ID. + rpc UploadPart(UploadPartRequest) returns (UploadPartResponse); + // CompleteUploadRequest marks a multipart upload as complete. + rpc CompleteUpload(CompleteUploadRequest) returns (CompleteUploadResponse); + + // RotateKey rotates the key pair used for encrypting session recording data. + rpc RotateKey(RotateKeyRequest) returns (RotateKeyResponse); + // GetRotationState returns whether or not a rotation is in progress. + rpc GetRotationState(GetRotationStateRequest) returns (GetRotationStateResponse); + // CompleteRotation moves rotated keys out of the active set. + rpc CompleteRotation(CompleteRotationRequest) returns (CompleteRotationResponse); + // RollbackRotation removes active keys and reverts rotating keys back to being active. + rpc RollbackRotation(RollbackRotationRequest) returns (RollbackRotationResponse); +} + +// The handle to an upload for an encrypted session. +message Upload { + // The primary identifier for an Upload. + string upload_id = 1; + // The session ID an upload is tied to. + string session_id = 2; + // The time that an upload was created at. + google.protobuf.Timestamp initiated_at = 3; +} + +// The request to start a multipart upload for a specific session recording. +message CreateUploadRequest { + // The session ID associated with the recording being uploaded. + string session_id = 1; +} + +// The resulting Upload message for a created Upload. +message CreateUploadResponse { + // The handle for the created Upload. + Upload upload = 1; +} + +// The request to upload a single part in a multipart upload. +message UploadPartRequest { + // The handle to the in-progress upload that should be uploaded to. + Upload upload = 1; + // The ordered index applied to the part. + int64 part_number = 2; + // The encrypted part of session recording data being uploaded. + bytes part = 3; +} + +// The resulting metadata about an uploaded part. +message Part { + // The ordered index applied to the part. + int64 part_number = 1; + // The part e-tag value relevant to some storage backends. + string etag = 2; +} + +// A successfully uploaded Part to be included in the final CompleteUpload request. +message UploadPartResponse { + // The resulting part metadata about an uploaded part. + Part part = 1; +} + +// The request to complete an upload. The included part numbers must match the parts successfully +// uploaded up until this point. +message CompleteUploadRequest { + // The handle to an upload to complete. + Upload upload = 1; + // The parts expected to be successfully uploaded. + repeated Part parts = 2; +} + +// The body of a CompleteUpload request. +message CompleteUploadResponse {} + +// The body of a RotateKey request. +message RotateKeyRequest {} + +// The return value of a RotateKey request. +message RotateKeyResponse {} + +// The body of a GetRotationState request. +message GetRotationStateRequest { + int32 page_size = 1; + string page_token = 2; +} + +// A public key fingerprint coupled with its current state. +message FingerprintWithState { + // A fingerprint identifying the public key of a KeyPair. + string fingerprint = 1; + // The state associated with the identified KeyPair. + v1.KeyPairState state = 2; +} + +// The current state of all active encryption key pairs. +message GetRotationStateResponse { + string next_page_token = 1; + // The state of all active encryption key pairs. + repeated FingerprintWithState key_pair_states = 2; +} + +// The body of a CompleteRotation request. +message CompleteRotationRequest {} + +// The return value of a CompleteRotation request. +message CompleteRotationResponse {} + +// The body of a RollbackRotation request. +message RollbackRotationRequest {} + +// The return value of a RollbackRotation request +message RollbackRotationResponse {} diff --git a/api/types/constants.go b/api/types/constants.go index 995c83d9fa1c7..80685712a9160 100644 --- a/api/types/constants.go +++ b/api/types/constants.go @@ -313,10 +313,20 @@ const ( // KindSessionRecordingConfig is the resource for session recording configuration. KindSessionRecordingConfig = "session_recording_config" + // KindRecordingEncryption is the collection of active session recording encryption keys. + KindRecordingEncryption = "recording_encryption" + + // KindRotatedKey is a previously rotated session recording encryption key kept for future replay. + KindRotatedKey = "rotated_key" + // MetaNameSessionRecordingConfig is the exact name of the singleton resource for // session recording configuration. MetaNameSessionRecordingConfig = "session-recording-config" + // MetaNameRecordingEncryption is the exact name of the singleton resource for + // session recording configuration. + MetaNameRecordingEncryption = "recording-encryption" + // KindExternalAuditStorage the resource kind for External Audit Storage // configuration. KindExternalAuditStorage = "external_audit_storage" diff --git a/api/types/resource.go b/api/types/resource.go index cb90ee098144c..ea7786c0b0775 100644 --- a/api/types/resource.go +++ b/api/types/resource.go @@ -761,7 +761,7 @@ func GetRevision(v any) (string, error) { case Resource: return r.GetRevision(), nil case ResourceMetadata: - return r.GetMetadata().Revision, nil + return r.GetMetadata().GetRevision(), nil } return "", trace.BadParameter("unable to determine revision from resource of type %T", v) } diff --git a/api/types/sessionrecording.go b/api/types/sessionrecording.go index 832bfcc59a8ec..ad1fc5af60c8f 100644 --- a/api/types/sessionrecording.go +++ b/api/types/sessionrecording.go @@ -17,6 +17,7 @@ limitations under the License. package types import ( + "iter" "slices" "strings" "time" @@ -43,8 +44,24 @@ type SessionRecordingConfig interface { // SetProxyChecksHostKeys sets if the proxy will check host keys. SetProxyChecksHostKeys(bool) + // GetEncrypted gets if session recordings should be encrypted or not. + GetEncrypted() bool + + // GetEncryptionConfig gets the encryption config from the session recording config. + GetEncryptionConfig() *SessionRecordingEncryptionConfig + + // GetEncryptionKeys gets the encryption keys for the session recording config. + GetEncryptionKeys() []*AgeEncryptionKey + + // SetEncryptionKeys sets the encryption keys for the session recording config. + // It returns true if there was a change applied and false otherwise. + SetEncryptionKeys(iter.Seq[*AgeEncryptionKey]) bool + // Clone returns a copy of the resource. Clone() SessionRecordingConfig + + // CheckAndSetDefaults verifies the constraints for a SessionRecordingConfig + CheckAndSetDefaults() error } // NewSessionRecordingConfigFromConfigFile is a convenience method to create @@ -163,6 +180,68 @@ func (c *SessionRecordingConfigV2) SetProxyChecksHostKeys(t bool) { c.Spec.ProxyChecksHostKeys = NewBoolOption(t) } +// GetEncrypted gets if session recordings should be encrypted or not. +func (c *SessionRecordingConfigV2) GetEncrypted() bool { + encryption := c.GetEncryptionConfig() + return encryption != nil && encryption.Enabled +} + +// GetEncryptionConfig gets the encryption config from the session recording config. +func (c *SessionRecordingConfigV2) GetEncryptionConfig() *SessionRecordingEncryptionConfig { + if c == nil { + return nil + } + + return c.Spec.Encryption +} + +// GetEncryptionKeys gets the encryption keys for the session recording config. +func (c *SessionRecordingConfigV2) GetEncryptionKeys() []*AgeEncryptionKey { + if c.Status != nil { + return c.Status.EncryptionKeys + } + + return nil +} + +// SetEncryptionKeys sets the encryption keys for the session recording config. +// It returns true if there was a change applied and false otherwise. +func (c *SessionRecordingConfigV2) SetEncryptionKeys(keys iter.Seq[*AgeEncryptionKey]) bool { + existingKeys := make(map[string]struct{}) + for _, key := range c.GetEncryptionKeys() { + existingKeys[string(key.PublicKey)] = struct{}{} + } + + var keysChanged bool + var newKeys []*AgeEncryptionKey + addedKeys := make(map[string]struct{}) + for key := range keys { + if !keysChanged { + if _, exists := existingKeys[string(key.PublicKey)]; !exists { + keysChanged = true + } + } + + if _, added := addedKeys[string(key.PublicKey)]; !added { + addedKeys[string(key.PublicKey)] = struct{}{} + newKeys = append(newKeys, key) + } + + } + + shouldUpdate := len(addedKeys) > 0 && (keysChanged || len(existingKeys) != len(addedKeys)) + if !shouldUpdate { + return false + } + + if c.Status == nil { + c.Status = &SessionRecordingConfigStatus{} + } + c.Status.EncryptionKeys = newKeys + + return true +} + // Clone returns a copy of the resource. func (c *SessionRecordingConfigV2) Clone() SessionRecordingConfig { return utils.CloneProtoMsg(c) diff --git a/api/types/sessionrecording_test.go b/api/types/sessionrecording_test.go new file mode 100644 index 0000000000000..375bef60ac9ab --- /dev/null +++ b/api/types/sessionrecording_test.go @@ -0,0 +1,187 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package types_test + +import ( + "slices" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/api/types" +) + +func TestSetEncryptionKeys(t *testing.T) { + cases := []struct { + name string + initialKeys []*types.AgeEncryptionKey + newKeys []*types.AgeEncryptionKey + expectChange bool + }{ + { + name: "adding new keys to empty list", + expectChange: true, + newKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + }, + }, { + name: "adding new keys to existing list", + expectChange: true, + initialKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + }, + newKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + { + PublicKey: []byte("789"), + }, + }, + }, { + name: "replacing existing keys", + expectChange: true, + initialKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + }, + newKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("321"), + }, + { + PublicKey: []byte("654"), + }, + }, + }, { + name: "removing from existing keys", + expectChange: true, + initialKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + { + PublicKey: []byte("789"), + }, + }, + newKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + }, + }, { + name: "try to remove all keys", + expectChange: false, + initialKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + { + PublicKey: []byte("789"), + }, + }, + }, { + name: "no change", + expectChange: false, + initialKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + }, + newKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + }, + }, { + name: "adding duplicates", + expectChange: false, + initialKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + }, + newKeys: []*types.AgeEncryptionKey{ + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("123"), + }, + { + PublicKey: []byte("456"), + }, + { + PublicKey: []byte("456"), + }, + }, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + src := &types.SessionRecordingConfigV2{ + Status: &types.SessionRecordingConfigStatus{ + EncryptionKeys: c.initialKeys, + }, + } + + keysChanged := src.SetEncryptionKeys(slices.Values(c.newKeys)) + require.Equal(t, c.expectChange, keysChanged) + if keysChanged { + require.Equal(t, c.newKeys, src.Status.EncryptionKeys) + } else { + require.Equal(t, c.initialKeys, src.Status.EncryptionKeys) + } + }) + } +} diff --git a/api/types/types.pb.go b/api/types/types.pb.go index 950876d428f25..deae0e1764cb3 100644 --- a/api/types/types.pb.go +++ b/api/types/types.pb.go @@ -1175,7 +1175,7 @@ func (x CertAuthoritySpecV2_SigningAlgType) String() string { } func (CertAuthoritySpecV2_SigningAlgType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{62, 0} + return fileDescriptor_9198ee693835762e, []int{64, 0} } // FIPSEndpointState represents an AWS FIPS endpoint state. @@ -1208,7 +1208,7 @@ func (x ClusterAuditConfigSpecV2_FIPSEndpointState) String() string { } func (ClusterAuditConfigSpecV2_FIPSEndpointState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{90, 0} + return fileDescriptor_9198ee693835762e, []int{92, 0} } // TraceType is an identification of the checkpoint. @@ -1278,7 +1278,7 @@ func (x ConnectionDiagnosticTrace_TraceType) String() string { } func (ConnectionDiagnosticTrace_TraceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{278, 0} + return fileDescriptor_9198ee693835762e, []int{284, 0} } // StatusType describes whether this was a success or a failure. @@ -1307,7 +1307,7 @@ func (x ConnectionDiagnosticTrace_StatusType) String() string { } func (ConnectionDiagnosticTrace_StatusType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{278, 1} + return fileDescriptor_9198ee693835762e, []int{284, 1} } // OktaAssignmentStatus represents the status of an Okta assignment. @@ -1347,7 +1347,7 @@ func (x OktaAssignmentSpecV1_OktaAssignmentStatus) String() string { } func (OktaAssignmentSpecV1_OktaAssignmentStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{370, 0} + return fileDescriptor_9198ee693835762e, []int{376, 0} } // OktaAssignmentTargetType is the type of Okta object that an assignment is targeting. @@ -1379,7 +1379,7 @@ func (x OktaAssignmentTargetV1_OktaAssignmentTargetType) String() string { } func (OktaAssignmentTargetV1_OktaAssignmentTargetType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{371, 0} + return fileDescriptor_9198ee693835762e, []int{377, 0} } type KeepAlive struct { @@ -4439,6 +4439,97 @@ func (m *JWTKeyPair) XXX_DiscardUnknown() { var xxx_messageInfo_JWTKeyPair proto.InternalMessageInfo +// EncryptionKeyPair is a PKIX ASN.1 DER encoded keypair used for encrypting and decrypting data. +type EncryptionKeyPair struct { + // PublicKey is a PKIX ASN.1 DER encoded public key. + PublicKey []byte `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + // PrivateKey is a PKCS#8 ASN.1 DER encoded private key. + PrivateKey []byte `protobuf:"bytes,2,opt,name=private_key,json=privateKey,proto3" json:"private_key,omitempty"` + // PrivateKeyType is the type of the PrivateKey. + PrivateKeyType PrivateKeyType `protobuf:"varint,3,opt,name=private_key_type,json=privateKeyType,proto3,enum=types.PrivateKeyType" json:"private_key_type,omitempty"` + // Hash function used during OAEP encryption/decryption. It maps directly to the possible + // values of [crypto.Hash] in the go crypto package. + Hash uint32 `protobuf:"varint,4,opt,name=hash,proto3" json:"hash,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EncryptionKeyPair) Reset() { *m = EncryptionKeyPair{} } +func (m *EncryptionKeyPair) String() string { return proto.CompactTextString(m) } +func (*EncryptionKeyPair) ProtoMessage() {} +func (*EncryptionKeyPair) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{61} +} +func (m *EncryptionKeyPair) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EncryptionKeyPair) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EncryptionKeyPair.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EncryptionKeyPair) XXX_Merge(src proto.Message) { + xxx_messageInfo_EncryptionKeyPair.Merge(m, src) +} +func (m *EncryptionKeyPair) XXX_Size() int { + return m.Size() +} +func (m *EncryptionKeyPair) XXX_DiscardUnknown() { + xxx_messageInfo_EncryptionKeyPair.DiscardUnknown(m) +} + +var xxx_messageInfo_EncryptionKeyPair proto.InternalMessageInfo + +// A public key to be used as a recipient during age encryption of session recordings. +type AgeEncryptionKey struct { + // A PKIX ASN.1 DER encoded public key used for key wrapping during age encryption. Expected to be RSA 4096. + PublicKey []byte `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AgeEncryptionKey) Reset() { *m = AgeEncryptionKey{} } +func (m *AgeEncryptionKey) String() string { return proto.CompactTextString(m) } +func (*AgeEncryptionKey) ProtoMessage() {} +func (*AgeEncryptionKey) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{62} +} +func (m *AgeEncryptionKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AgeEncryptionKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AgeEncryptionKey.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AgeEncryptionKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_AgeEncryptionKey.Merge(m, src) +} +func (m *AgeEncryptionKey) XXX_Size() int { + return m.Size() +} +func (m *AgeEncryptionKey) XXX_DiscardUnknown() { + xxx_messageInfo_AgeEncryptionKey.DiscardUnknown(m) +} + +var xxx_messageInfo_AgeEncryptionKey proto.InternalMessageInfo + // CertAuthorityV2 is version 2 resource spec for Cert Authority type CertAuthorityV2 struct { // Kind is a resource kind @@ -4459,7 +4550,7 @@ type CertAuthorityV2 struct { func (m *CertAuthorityV2) Reset() { *m = CertAuthorityV2{} } func (*CertAuthorityV2) ProtoMessage() {} func (*CertAuthorityV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{61} + return fileDescriptor_9198ee693835762e, []int{63} } func (m *CertAuthorityV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4520,7 +4611,7 @@ func (m *CertAuthoritySpecV2) Reset() { *m = CertAuthoritySpecV2{} } func (m *CertAuthoritySpecV2) String() string { return proto.CompactTextString(m) } func (*CertAuthoritySpecV2) ProtoMessage() {} func (*CertAuthoritySpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{62} + return fileDescriptor_9198ee693835762e, []int{64} } func (m *CertAuthoritySpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4566,7 +4657,7 @@ func (m *CAKeySet) Reset() { *m = CAKeySet{} } func (m *CAKeySet) String() string { return proto.CompactTextString(m) } func (*CAKeySet) ProtoMessage() {} func (*CAKeySet) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{63} + return fileDescriptor_9198ee693835762e, []int{65} } func (m *CAKeySet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4611,7 +4702,7 @@ func (m *RoleMapping) Reset() { *m = RoleMapping{} } func (m *RoleMapping) String() string { return proto.CompactTextString(m) } func (*RoleMapping) ProtoMessage() {} func (*RoleMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{64} + return fileDescriptor_9198ee693835762e, []int{66} } func (m *RoleMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4659,7 +4750,7 @@ type ProvisionTokenV1 struct { func (m *ProvisionTokenV1) Reset() { *m = ProvisionTokenV1{} } func (*ProvisionTokenV1) ProtoMessage() {} func (*ProvisionTokenV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{65} + return fileDescriptor_9198ee693835762e, []int{67} } func (m *ProvisionTokenV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4712,7 +4803,7 @@ type ProvisionTokenV2 struct { func (m *ProvisionTokenV2) Reset() { *m = ProvisionTokenV2{} } func (*ProvisionTokenV2) ProtoMessage() {} func (*ProvisionTokenV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{66} + return fileDescriptor_9198ee693835762e, []int{68} } func (m *ProvisionTokenV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4754,7 +4845,7 @@ func (m *ProvisionTokenV2List) Reset() { *m = ProvisionTokenV2List{} } func (m *ProvisionTokenV2List) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenV2List) ProtoMessage() {} func (*ProvisionTokenV2List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{67} + return fileDescriptor_9198ee693835762e, []int{69} } func (m *ProvisionTokenV2List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4806,7 +4897,7 @@ func (m *TokenRule) Reset() { *m = TokenRule{} } func (m *TokenRule) String() string { return proto.CompactTextString(m) } func (*TokenRule) ProtoMessage() {} func (*TokenRule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{68} + return fileDescriptor_9198ee693835762e, []int{70} } func (m *TokenRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4896,7 +4987,7 @@ func (m *ProvisionTokenSpecV2) Reset() { *m = ProvisionTokenSpecV2{} } func (m *ProvisionTokenSpecV2) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2) ProtoMessage() {} func (*ProvisionTokenSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{69} + return fileDescriptor_9198ee693835762e, []int{71} } func (m *ProvisionTokenSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4945,7 +5036,7 @@ func (m *ProvisionTokenSpecV2AzureDevops) Reset() { *m = ProvisionTokenS func (m *ProvisionTokenSpecV2AzureDevops) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2AzureDevops) ProtoMessage() {} func (*ProvisionTokenSpecV2AzureDevops) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{70} + return fileDescriptor_9198ee693835762e, []int{72} } func (m *ProvisionTokenSpecV2AzureDevops) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5017,7 +5108,7 @@ func (m *ProvisionTokenSpecV2AzureDevops_Rule) Reset() { *m = ProvisionT func (m *ProvisionTokenSpecV2AzureDevops_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2AzureDevops_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2AzureDevops_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{70, 0} + return fileDescriptor_9198ee693835762e, []int{72, 0} } func (m *ProvisionTokenSpecV2AzureDevops_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5069,7 +5160,7 @@ func (m *ProvisionTokenSpecV2TPM) Reset() { *m = ProvisionTokenSpecV2TPM func (m *ProvisionTokenSpecV2TPM) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2TPM) ProtoMessage() {} func (*ProvisionTokenSpecV2TPM) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{71} + return fileDescriptor_9198ee693835762e, []int{73} } func (m *ProvisionTokenSpecV2TPM) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5125,7 +5216,7 @@ func (m *ProvisionTokenSpecV2TPM_Rule) Reset() { *m = ProvisionTokenSpec func (m *ProvisionTokenSpecV2TPM_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2TPM_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2TPM_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{71, 0} + return fileDescriptor_9198ee693835762e, []int{73, 0} } func (m *ProvisionTokenSpecV2TPM_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5194,7 +5285,7 @@ func (m *ProvisionTokenSpecV2GitHub) Reset() { *m = ProvisionTokenSpecV2 func (m *ProvisionTokenSpecV2GitHub) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GitHub) ProtoMessage() {} func (*ProvisionTokenSpecV2GitHub) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{72} + return fileDescriptor_9198ee693835762e, []int{74} } func (m *ProvisionTokenSpecV2GitHub) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5256,7 +5347,7 @@ func (m *ProvisionTokenSpecV2GitHub_Rule) Reset() { *m = ProvisionTokenS func (m *ProvisionTokenSpecV2GitHub_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GitHub_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2GitHub_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{72, 0} + return fileDescriptor_9198ee693835762e, []int{74, 0} } func (m *ProvisionTokenSpecV2GitHub_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5309,7 +5400,7 @@ func (m *ProvisionTokenSpecV2GitLab) Reset() { *m = ProvisionTokenSpecV2 func (m *ProvisionTokenSpecV2GitLab) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GitLab) ProtoMessage() {} func (*ProvisionTokenSpecV2GitLab) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{73} + return fileDescriptor_9198ee693835762e, []int{75} } func (m *ProvisionTokenSpecV2GitLab) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5411,7 +5502,7 @@ func (m *ProvisionTokenSpecV2GitLab_Rule) Reset() { *m = ProvisionTokenS func (m *ProvisionTokenSpecV2GitLab_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GitLab_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2GitLab_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{73, 0} + return fileDescriptor_9198ee693835762e, []int{75, 0} } func (m *ProvisionTokenSpecV2GitLab_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5456,7 +5547,7 @@ func (m *ProvisionTokenSpecV2CircleCI) Reset() { *m = ProvisionTokenSpec func (m *ProvisionTokenSpecV2CircleCI) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2CircleCI) ProtoMessage() {} func (*ProvisionTokenSpecV2CircleCI) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{74} + return fileDescriptor_9198ee693835762e, []int{76} } func (m *ProvisionTokenSpecV2CircleCI) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5497,7 +5588,7 @@ func (m *ProvisionTokenSpecV2CircleCI_Rule) Reset() { *m = ProvisionToke func (m *ProvisionTokenSpecV2CircleCI_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2CircleCI_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2CircleCI_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{74, 0} + return fileDescriptor_9198ee693835762e, []int{76, 0} } func (m *ProvisionTokenSpecV2CircleCI_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5547,7 +5638,7 @@ func (m *ProvisionTokenSpecV2Spacelift) Reset() { *m = ProvisionTokenSpe func (m *ProvisionTokenSpecV2Spacelift) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Spacelift) ProtoMessage() {} func (*ProvisionTokenSpecV2Spacelift) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{75} + return fileDescriptor_9198ee693835762e, []int{77} } func (m *ProvisionTokenSpecV2Spacelift) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5606,7 +5697,7 @@ func (m *ProvisionTokenSpecV2Spacelift_Rule) Reset() { *m = ProvisionTok func (m *ProvisionTokenSpecV2Spacelift_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Spacelift_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2Spacelift_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{75, 0} + return fileDescriptor_9198ee693835762e, []int{77, 0} } func (m *ProvisionTokenSpecV2Spacelift_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5661,7 +5752,7 @@ func (m *ProvisionTokenSpecV2Kubernetes) Reset() { *m = ProvisionTokenSp func (m *ProvisionTokenSpecV2Kubernetes) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Kubernetes) ProtoMessage() {} func (*ProvisionTokenSpecV2Kubernetes) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{76} + return fileDescriptor_9198ee693835762e, []int{78} } func (m *ProvisionTokenSpecV2Kubernetes) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5708,7 +5799,7 @@ func (m *ProvisionTokenSpecV2Kubernetes_StaticJWKSConfig) String() string { } func (*ProvisionTokenSpecV2Kubernetes_StaticJWKSConfig) ProtoMessage() {} func (*ProvisionTokenSpecV2Kubernetes_StaticJWKSConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{76, 0} + return fileDescriptor_9198ee693835762e, []int{78, 0} } func (m *ProvisionTokenSpecV2Kubernetes_StaticJWKSConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5760,7 +5851,7 @@ func (m *ProvisionTokenSpecV2Kubernetes_OIDCConfig) String() string { } func (*ProvisionTokenSpecV2Kubernetes_OIDCConfig) ProtoMessage() {} func (*ProvisionTokenSpecV2Kubernetes_OIDCConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{76, 1} + return fileDescriptor_9198ee693835762e, []int{78, 1} } func (m *ProvisionTokenSpecV2Kubernetes_OIDCConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5804,7 +5895,7 @@ func (m *ProvisionTokenSpecV2Kubernetes_Rule) Reset() { *m = ProvisionTo func (m *ProvisionTokenSpecV2Kubernetes_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Kubernetes_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2Kubernetes_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{76, 2} + return fileDescriptor_9198ee693835762e, []int{78, 2} } func (m *ProvisionTokenSpecV2Kubernetes_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5848,7 +5939,7 @@ func (m *ProvisionTokenSpecV2Azure) Reset() { *m = ProvisionTokenSpecV2A func (m *ProvisionTokenSpecV2Azure) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Azure) ProtoMessage() {} func (*ProvisionTokenSpecV2Azure) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{77} + return fileDescriptor_9198ee693835762e, []int{79} } func (m *ProvisionTokenSpecV2Azure) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5894,7 +5985,7 @@ func (m *ProvisionTokenSpecV2Azure_Rule) Reset() { *m = ProvisionTokenSp func (m *ProvisionTokenSpecV2Azure_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Azure_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2Azure_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{77, 0} + return fileDescriptor_9198ee693835762e, []int{79, 0} } func (m *ProvisionTokenSpecV2Azure_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5938,7 +6029,7 @@ func (m *ProvisionTokenSpecV2GCP) Reset() { *m = ProvisionTokenSpecV2GCP func (m *ProvisionTokenSpecV2GCP) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GCP) ProtoMessage() {} func (*ProvisionTokenSpecV2GCP) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{78} + return fileDescriptor_9198ee693835762e, []int{80} } func (m *ProvisionTokenSpecV2GCP) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5987,7 +6078,7 @@ func (m *ProvisionTokenSpecV2GCP_Rule) Reset() { *m = ProvisionTokenSpec func (m *ProvisionTokenSpecV2GCP_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2GCP_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2GCP_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{78, 0} + return fileDescriptor_9198ee693835762e, []int{80, 0} } func (m *ProvisionTokenSpecV2GCP_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6044,7 +6135,7 @@ func (m *ProvisionTokenSpecV2TerraformCloud) Reset() { *m = ProvisionTok func (m *ProvisionTokenSpecV2TerraformCloud) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2TerraformCloud) ProtoMessage() {} func (*ProvisionTokenSpecV2TerraformCloud) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{79} + return fileDescriptor_9198ee693835762e, []int{81} } func (m *ProvisionTokenSpecV2TerraformCloud) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6109,7 +6200,7 @@ func (m *ProvisionTokenSpecV2TerraformCloud_Rule) Reset() { func (m *ProvisionTokenSpecV2TerraformCloud_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2TerraformCloud_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2TerraformCloud_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{79, 0} + return fileDescriptor_9198ee693835762e, []int{81, 0} } func (m *ProvisionTokenSpecV2TerraformCloud_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6161,7 +6252,7 @@ func (m *ProvisionTokenSpecV2Bitbucket) Reset() { *m = ProvisionTokenSpe func (m *ProvisionTokenSpecV2Bitbucket) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Bitbucket) ProtoMessage() {} func (*ProvisionTokenSpecV2Bitbucket) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{80} + return fileDescriptor_9198ee693835762e, []int{82} } func (m *ProvisionTokenSpecV2Bitbucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6219,7 +6310,7 @@ func (m *ProvisionTokenSpecV2Bitbucket_Rule) Reset() { *m = ProvisionTok func (m *ProvisionTokenSpecV2Bitbucket_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Bitbucket_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2Bitbucket_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{80, 0} + return fileDescriptor_9198ee693835762e, []int{82, 0} } func (m *ProvisionTokenSpecV2Bitbucket_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6263,7 +6354,7 @@ func (m *ProvisionTokenSpecV2Oracle) Reset() { *m = ProvisionTokenSpecV2 func (m *ProvisionTokenSpecV2Oracle) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Oracle) ProtoMessage() {} func (*ProvisionTokenSpecV2Oracle) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{81} + return fileDescriptor_9198ee693835762e, []int{83} } func (m *ProvisionTokenSpecV2Oracle) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6314,7 +6405,7 @@ func (m *ProvisionTokenSpecV2Oracle_Rule) Reset() { *m = ProvisionTokenS func (m *ProvisionTokenSpecV2Oracle_Rule) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2Oracle_Rule) ProtoMessage() {} func (*ProvisionTokenSpecV2Oracle_Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{81, 0} + return fileDescriptor_9198ee693835762e, []int{83, 0} } func (m *ProvisionTokenSpecV2Oracle_Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6366,7 +6457,7 @@ func (m *ProvisionTokenSpecV2BoundKeypair) Reset() { *m = ProvisionToken func (m *ProvisionTokenSpecV2BoundKeypair) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenSpecV2BoundKeypair) ProtoMessage() {} func (*ProvisionTokenSpecV2BoundKeypair) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{82} + return fileDescriptor_9198ee693835762e, []int{84} } func (m *ProvisionTokenSpecV2BoundKeypair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6432,7 +6523,7 @@ func (m *ProvisionTokenSpecV2BoundKeypair_OnboardingSpec) String() string { } func (*ProvisionTokenSpecV2BoundKeypair_OnboardingSpec) ProtoMessage() {} func (*ProvisionTokenSpecV2BoundKeypair_OnboardingSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{82, 0} + return fileDescriptor_9198ee693835762e, []int{84, 0} } func (m *ProvisionTokenSpecV2BoundKeypair_OnboardingSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6500,7 +6591,7 @@ func (m *ProvisionTokenSpecV2BoundKeypair_RecoverySpec) String() string { } func (*ProvisionTokenSpecV2BoundKeypair_RecoverySpec) ProtoMessage() {} func (*ProvisionTokenSpecV2BoundKeypair_RecoverySpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{82, 1} + return fileDescriptor_9198ee693835762e, []int{84, 1} } func (m *ProvisionTokenSpecV2BoundKeypair_RecoverySpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6544,7 +6635,7 @@ func (m *ProvisionTokenStatusV2) Reset() { *m = ProvisionTokenStatusV2{} func (m *ProvisionTokenStatusV2) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenStatusV2) ProtoMessage() {} func (*ProvisionTokenStatusV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{83} + return fileDescriptor_9198ee693835762e, []int{85} } func (m *ProvisionTokenStatusV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6619,7 +6710,7 @@ func (m *ProvisionTokenStatusV2BoundKeypair) Reset() { *m = ProvisionTok func (m *ProvisionTokenStatusV2BoundKeypair) String() string { return proto.CompactTextString(m) } func (*ProvisionTokenStatusV2BoundKeypair) ProtoMessage() {} func (*ProvisionTokenStatusV2BoundKeypair) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{84} + return fileDescriptor_9198ee693835762e, []int{86} } func (m *ProvisionTokenStatusV2BoundKeypair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6668,7 +6759,7 @@ type StaticTokensV2 struct { func (m *StaticTokensV2) Reset() { *m = StaticTokensV2{} } func (*StaticTokensV2) ProtoMessage() {} func (*StaticTokensV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{85} + return fileDescriptor_9198ee693835762e, []int{87} } func (m *StaticTokensV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6711,7 +6802,7 @@ func (m *StaticTokensSpecV2) Reset() { *m = StaticTokensSpecV2{} } func (m *StaticTokensSpecV2) String() string { return proto.CompactTextString(m) } func (*StaticTokensSpecV2) ProtoMessage() {} func (*StaticTokensSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{86} + return fileDescriptor_9198ee693835762e, []int{88} } func (m *StaticTokensSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6760,7 +6851,7 @@ type ClusterNameV2 struct { func (m *ClusterNameV2) Reset() { *m = ClusterNameV2{} } func (*ClusterNameV2) ProtoMessage() {} func (*ClusterNameV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{87} + return fileDescriptor_9198ee693835762e, []int{89} } func (m *ClusterNameV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6806,7 +6897,7 @@ func (m *ClusterNameSpecV2) Reset() { *m = ClusterNameSpecV2{} } func (m *ClusterNameSpecV2) String() string { return proto.CompactTextString(m) } func (*ClusterNameSpecV2) ProtoMessage() {} func (*ClusterNameSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{88} + return fileDescriptor_9198ee693835762e, []int{90} } func (m *ClusterNameSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6856,7 +6947,7 @@ func (m *ClusterAuditConfigV2) Reset() { *m = ClusterAuditConfigV2{} } func (m *ClusterAuditConfigV2) String() string { return proto.CompactTextString(m) } func (*ClusterAuditConfigV2) ProtoMessage() {} func (*ClusterAuditConfigV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{89} + return fileDescriptor_9198ee693835762e, []int{91} } func (m *ClusterAuditConfigV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6926,7 +7017,7 @@ func (m *ClusterAuditConfigSpecV2) Reset() { *m = ClusterAuditConfigSpec func (m *ClusterAuditConfigSpecV2) String() string { return proto.CompactTextString(m) } func (*ClusterAuditConfigSpecV2) ProtoMessage() {} func (*ClusterAuditConfigSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{90} + return fileDescriptor_9198ee693835762e, []int{92} } func (m *ClusterAuditConfigSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6977,7 +7068,7 @@ func (m *ClusterNetworkingConfigV2) Reset() { *m = ClusterNetworkingConf func (m *ClusterNetworkingConfigV2) String() string { return proto.CompactTextString(m) } func (*ClusterNetworkingConfigV2) ProtoMessage() {} func (*ClusterNetworkingConfigV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{91} + return fileDescriptor_9198ee693835762e, []int{93} } func (m *ClusterNetworkingConfigV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7056,7 +7147,7 @@ func (m *ClusterNetworkingConfigSpecV2) Reset() { *m = ClusterNetworking func (m *ClusterNetworkingConfigSpecV2) String() string { return proto.CompactTextString(m) } func (*ClusterNetworkingConfigSpecV2) ProtoMessage() {} func (*ClusterNetworkingConfigSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{92} + return fileDescriptor_9198ee693835762e, []int{94} } func (m *ClusterNetworkingConfigSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7100,7 +7191,7 @@ func (m *TunnelStrategyV1) Reset() { *m = TunnelStrategyV1{} } func (m *TunnelStrategyV1) String() string { return proto.CompactTextString(m) } func (*TunnelStrategyV1) ProtoMessage() {} func (*TunnelStrategyV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{93} + return fileDescriptor_9198ee693835762e, []int{95} } func (m *TunnelStrategyV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7185,7 +7276,7 @@ func (m *AgentMeshTunnelStrategy) Reset() { *m = AgentMeshTunnelStrategy func (m *AgentMeshTunnelStrategy) String() string { return proto.CompactTextString(m) } func (*AgentMeshTunnelStrategy) ProtoMessage() {} func (*AgentMeshTunnelStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{94} + return fileDescriptor_9198ee693835762e, []int{96} } func (m *AgentMeshTunnelStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7226,7 +7317,7 @@ func (m *ProxyPeeringTunnelStrategy) Reset() { *m = ProxyPeeringTunnelSt func (m *ProxyPeeringTunnelStrategy) String() string { return proto.CompactTextString(m) } func (*ProxyPeeringTunnelStrategy) ProtoMessage() {} func (*ProxyPeeringTunnelStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{95} + return fileDescriptor_9198ee693835762e, []int{97} } func (m *ProxyPeeringTunnelStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7267,17 +7358,19 @@ type SessionRecordingConfigV2 struct { // Metadata is resource metadata Metadata Metadata `protobuf:"bytes,4,opt,name=Metadata,proto3" json:"metadata"` // Spec is a SessionRecordingConfig specification - Spec SessionRecordingConfigSpecV2 `protobuf:"bytes,5,opt,name=Spec,proto3" json:"spec"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Spec SessionRecordingConfigSpecV2 `protobuf:"bytes,5,opt,name=Spec,proto3" json:"spec"` + // Status is the SessionRecordingConfig status containing active encryption keys + Status *SessionRecordingConfigStatus `protobuf:"bytes,6,opt,name=Status,proto3" json:"status,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *SessionRecordingConfigV2) Reset() { *m = SessionRecordingConfigV2{} } func (m *SessionRecordingConfigV2) String() string { return proto.CompactTextString(m) } func (*SessionRecordingConfigV2) ProtoMessage() {} func (*SessionRecordingConfigV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{96} + return fileDescriptor_9198ee693835762e, []int{98} } func (m *SessionRecordingConfigV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7306,6 +7399,144 @@ func (m *SessionRecordingConfigV2) XXX_DiscardUnknown() { var xxx_messageInfo_SessionRecordingConfigV2 proto.InternalMessageInfo +// KeyLabel combines a label that can be used to identify one or more keys with a keystore type that +// determines where the keys can be found. +type KeyLabel struct { + // Type represents which keystore should be searched when looking up keys by label. + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type"` + // Label is a value that can be used with the related keystore in order to find relevant keys. + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *KeyLabel) Reset() { *m = KeyLabel{} } +func (m *KeyLabel) String() string { return proto.CompactTextString(m) } +func (*KeyLabel) ProtoMessage() {} +func (*KeyLabel) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{99} +} +func (m *KeyLabel) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *KeyLabel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_KeyLabel.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *KeyLabel) XXX_Merge(src proto.Message) { + xxx_messageInfo_KeyLabel.Merge(m, src) +} +func (m *KeyLabel) XXX_Size() int { + return m.Size() +} +func (m *KeyLabel) XXX_DiscardUnknown() { + xxx_messageInfo_KeyLabel.DiscardUnknown(m) +} + +var xxx_messageInfo_KeyLabel proto.InternalMessageInfo + +// ManualKeyManagementConfig defines whether or not recording encryption keys should be managed externally +// and how to query those keys. +type ManualKeyManagementConfig struct { + // Enabled controls whether or recording encryption keys should be managed externally. + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + // ActiveKeys describe which keys should be queried for active recording encryption and replay. + ActiveKeys []*KeyLabel `protobuf:"bytes,2,rep,name=active_keys,json=activeKeys,proto3" json:"active_keys,omitempty"` + // RotatedKeys describe which keys should be queried for historical replay. + RotatedKeys []*KeyLabel `protobuf:"bytes,3,rep,name=rotated_keys,json=rotatedKeys,proto3" json:"rotated_keys,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ManualKeyManagementConfig) Reset() { *m = ManualKeyManagementConfig{} } +func (m *ManualKeyManagementConfig) String() string { return proto.CompactTextString(m) } +func (*ManualKeyManagementConfig) ProtoMessage() {} +func (*ManualKeyManagementConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{100} +} +func (m *ManualKeyManagementConfig) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ManualKeyManagementConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ManualKeyManagementConfig.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ManualKeyManagementConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_ManualKeyManagementConfig.Merge(m, src) +} +func (m *ManualKeyManagementConfig) XXX_Size() int { + return m.Size() +} +func (m *ManualKeyManagementConfig) XXX_DiscardUnknown() { + xxx_messageInfo_ManualKeyManagementConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_ManualKeyManagementConfig proto.InternalMessageInfo + +// SessionRecordingEncryptionConfig configures if and how session recordings +// should be encrypted. +type SessionRecordingEncryptionConfig struct { + // Enabled controls whether or not session recordings should be encrypted. + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + // ManualKeyManagement defines whether or not recording encryption keys should be managed externally + // and how to query those keys. + ManualKeyManagement *ManualKeyManagementConfig `protobuf:"bytes,2,opt,name=manual_key_management,json=manualKeyManagement,proto3" json:"manual_key_management,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SessionRecordingEncryptionConfig) Reset() { *m = SessionRecordingEncryptionConfig{} } +func (m *SessionRecordingEncryptionConfig) String() string { return proto.CompactTextString(m) } +func (*SessionRecordingEncryptionConfig) ProtoMessage() {} +func (*SessionRecordingEncryptionConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{101} +} +func (m *SessionRecordingEncryptionConfig) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SessionRecordingEncryptionConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SessionRecordingEncryptionConfig.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SessionRecordingEncryptionConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_SessionRecordingEncryptionConfig.Merge(m, src) +} +func (m *SessionRecordingEncryptionConfig) XXX_Size() int { + return m.Size() +} +func (m *SessionRecordingEncryptionConfig) XXX_DiscardUnknown() { + xxx_messageInfo_SessionRecordingEncryptionConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_SessionRecordingEncryptionConfig proto.InternalMessageInfo + // SessionRecordingConfigSpecV2 is the actual data we care about // for SessionRecordingConfig. type SessionRecordingConfigSpecV2 struct { @@ -7313,17 +7544,19 @@ type SessionRecordingConfigSpecV2 struct { Mode string `protobuf:"bytes,1,opt,name=Mode,proto3" json:"mode"` // ProxyChecksHostKeys is used to control if the proxy will check host keys // when in recording mode. - ProxyChecksHostKeys *BoolOption `protobuf:"bytes,2,opt,name=ProxyChecksHostKeys,proto3,customtype=BoolOption" json:"proxy_checks_host_keys"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ProxyChecksHostKeys *BoolOption `protobuf:"bytes,2,opt,name=ProxyChecksHostKeys,proto3,customtype=BoolOption" json:"proxy_checks_host_keys"` + // Encryption configures if and how session recordings should be encrypted. + Encryption *SessionRecordingEncryptionConfig `protobuf:"bytes,3,opt,name=encryption,proto3" json:"encryption,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *SessionRecordingConfigSpecV2) Reset() { *m = SessionRecordingConfigSpecV2{} } func (m *SessionRecordingConfigSpecV2) String() string { return proto.CompactTextString(m) } func (*SessionRecordingConfigSpecV2) ProtoMessage() {} func (*SessionRecordingConfigSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{97} + return fileDescriptor_9198ee693835762e, []int{102} } func (m *SessionRecordingConfigSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7352,6 +7585,50 @@ func (m *SessionRecordingConfigSpecV2) XXX_DiscardUnknown() { var xxx_messageInfo_SessionRecordingConfigSpecV2 proto.InternalMessageInfo +// SessionRecordingConfigStatus contains the currently active age encryption keys used +// for encrypted session recording. +type SessionRecordingConfigStatus struct { + // EncryptionKeys contain the currently active age encryption keys used for + // encrypted session recording. + EncryptionKeys []*AgeEncryptionKey `protobuf:"bytes,1,rep,name=encryption_keys,json=encryptionKeys,proto3" json:"encryption_keys"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SessionRecordingConfigStatus) Reset() { *m = SessionRecordingConfigStatus{} } +func (m *SessionRecordingConfigStatus) String() string { return proto.CompactTextString(m) } +func (*SessionRecordingConfigStatus) ProtoMessage() {} +func (*SessionRecordingConfigStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_9198ee693835762e, []int{103} +} +func (m *SessionRecordingConfigStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SessionRecordingConfigStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SessionRecordingConfigStatus.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SessionRecordingConfigStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_SessionRecordingConfigStatus.Merge(m, src) +} +func (m *SessionRecordingConfigStatus) XXX_Size() int { + return m.Size() +} +func (m *SessionRecordingConfigStatus) XXX_DiscardUnknown() { + xxx_messageInfo_SessionRecordingConfigStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_SessionRecordingConfigStatus proto.InternalMessageInfo + // AuthPreferenceV2 implements the AuthPreference interface. type AuthPreferenceV2 struct { // Kind is a resource kind @@ -7373,7 +7650,7 @@ type AuthPreferenceV2 struct { func (m *AuthPreferenceV2) Reset() { *m = AuthPreferenceV2{} } func (*AuthPreferenceV2) ProtoMessage() {} func (*AuthPreferenceV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{98} + return fileDescriptor_9198ee693835762e, []int{104} } func (m *AuthPreferenceV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7472,7 +7749,7 @@ func (m *AuthPreferenceSpecV2) Reset() { *m = AuthPreferenceSpecV2{} } func (m *AuthPreferenceSpecV2) String() string { return proto.CompactTextString(m) } func (*AuthPreferenceSpecV2) ProtoMessage() {} func (*AuthPreferenceSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{99} + return fileDescriptor_9198ee693835762e, []int{105} } func (m *AuthPreferenceSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7523,7 +7800,7 @@ func (m *StableUNIXUserConfig) Reset() { *m = StableUNIXUserConfig{} } func (m *StableUNIXUserConfig) String() string { return proto.CompactTextString(m) } func (*StableUNIXUserConfig) ProtoMessage() {} func (*StableUNIXUserConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{100} + return fileDescriptor_9198ee693835762e, []int{106} } func (m *StableUNIXUserConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7574,7 +7851,7 @@ func (m *U2F) Reset() { *m = U2F{} } func (m *U2F) String() string { return proto.CompactTextString(m) } func (*U2F) ProtoMessage() {} func (*U2F) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{101} + return fileDescriptor_9198ee693835762e, []int{107} } func (m *U2F) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7642,7 +7919,7 @@ func (m *Webauthn) Reset() { *m = Webauthn{} } func (m *Webauthn) String() string { return proto.CompactTextString(m) } func (*Webauthn) ProtoMessage() {} func (*Webauthn) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{102} + return fileDescriptor_9198ee693835762e, []int{108} } func (m *Webauthn) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7715,7 +7992,7 @@ func (m *DeviceTrust) Reset() { *m = DeviceTrust{} } func (m *DeviceTrust) String() string { return proto.CompactTextString(m) } func (*DeviceTrust) ProtoMessage() {} func (*DeviceTrust) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{103} + return fileDescriptor_9198ee693835762e, []int{109} } func (m *DeviceTrust) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7765,7 +8042,7 @@ func (m *HardwareKey) Reset() { *m = HardwareKey{} } func (m *HardwareKey) String() string { return proto.CompactTextString(m) } func (*HardwareKey) ProtoMessage() {} func (*HardwareKey) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{104} + return fileDescriptor_9198ee693835762e, []int{110} } func (m *HardwareKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7812,7 +8089,7 @@ func (m *HardwareKeySerialNumberValidation) Reset() { *m = HardwareKeySe func (m *HardwareKeySerialNumberValidation) String() string { return proto.CompactTextString(m) } func (*HardwareKeySerialNumberValidation) ProtoMessage() {} func (*HardwareKeySerialNumberValidation) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{105} + return fileDescriptor_9198ee693835762e, []int{111} } func (m *HardwareKeySerialNumberValidation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7862,7 +8139,7 @@ func (m *Namespace) Reset() { *m = Namespace{} } func (m *Namespace) String() string { return proto.CompactTextString(m) } func (*Namespace) ProtoMessage() {} func (*Namespace) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{106} + return fileDescriptor_9198ee693835762e, []int{112} } func (m *Namespace) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7902,7 +8179,7 @@ func (m *NamespaceSpec) Reset() { *m = NamespaceSpec{} } func (m *NamespaceSpec) String() string { return proto.CompactTextString(m) } func (*NamespaceSpec) ProtoMessage() {} func (*NamespaceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{107} + return fileDescriptor_9198ee693835762e, []int{113} } func (m *NamespaceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7950,7 +8227,7 @@ type UserTokenV3 struct { func (m *UserTokenV3) Reset() { *m = UserTokenV3{} } func (*UserTokenV3) ProtoMessage() {} func (*UserTokenV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{108} + return fileDescriptor_9198ee693835762e, []int{114} } func (m *UserTokenV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7997,7 +8274,7 @@ func (m *UserTokenSpecV3) Reset() { *m = UserTokenSpecV3{} } func (m *UserTokenSpecV3) String() string { return proto.CompactTextString(m) } func (*UserTokenSpecV3) ProtoMessage() {} func (*UserTokenSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{109} + return fileDescriptor_9198ee693835762e, []int{115} } func (m *UserTokenSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8045,7 +8322,7 @@ type UserTokenSecretsV3 struct { func (m *UserTokenSecretsV3) Reset() { *m = UserTokenSecretsV3{} } func (*UserTokenSecretsV3) ProtoMessage() {} func (*UserTokenSecretsV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{110} + return fileDescriptor_9198ee693835762e, []int{116} } func (m *UserTokenSecretsV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8090,7 +8367,7 @@ func (m *UserTokenSecretsSpecV3) Reset() { *m = UserTokenSecretsSpecV3{} func (m *UserTokenSecretsSpecV3) String() string { return proto.CompactTextString(m) } func (*UserTokenSecretsSpecV3) ProtoMessage() {} func (*UserTokenSecretsSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{111} + return fileDescriptor_9198ee693835762e, []int{117} } func (m *UserTokenSecretsSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8139,7 +8416,7 @@ type AccessRequestV3 struct { func (m *AccessRequestV3) Reset() { *m = AccessRequestV3{} } func (*AccessRequestV3) ProtoMessage() {} func (*AccessRequestV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{112} + return fileDescriptor_9198ee693835762e, []int{118} } func (m *AccessRequestV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8191,7 +8468,7 @@ func (m *AccessReviewThreshold) Reset() { *m = AccessReviewThreshold{} } func (m *AccessReviewThreshold) String() string { return proto.CompactTextString(m) } func (*AccessReviewThreshold) ProtoMessage() {} func (*AccessReviewThreshold) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{113} + return fileDescriptor_9198ee693835762e, []int{119} } func (m *AccessReviewThreshold) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8236,7 +8513,7 @@ func (m *PromotedAccessList) Reset() { *m = PromotedAccessList{} } func (m *PromotedAccessList) String() string { return proto.CompactTextString(m) } func (*PromotedAccessList) ProtoMessage() {} func (*PromotedAccessList) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{114} + return fileDescriptor_9198ee693835762e, []int{120} } func (m *PromotedAccessList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8281,7 +8558,7 @@ func (m *AccessRequestDryRunEnrichment) Reset() { *m = AccessRequestDryR func (m *AccessRequestDryRunEnrichment) String() string { return proto.CompactTextString(m) } func (*AccessRequestDryRunEnrichment) ProtoMessage() {} func (*AccessRequestDryRunEnrichment) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{115} + return fileDescriptor_9198ee693835762e, []int{121} } func (m *AccessRequestDryRunEnrichment) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8342,7 +8619,7 @@ func (m *AccessReview) Reset() { *m = AccessReview{} } func (m *AccessReview) String() string { return proto.CompactTextString(m) } func (*AccessReview) ProtoMessage() {} func (*AccessReview) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{116} + return fileDescriptor_9198ee693835762e, []int{122} } func (m *AccessReview) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8387,7 +8664,7 @@ func (m *AccessReviewSubmission) Reset() { *m = AccessReviewSubmission{} func (m *AccessReviewSubmission) String() string { return proto.CompactTextString(m) } func (*AccessReviewSubmission) ProtoMessage() {} func (*AccessReviewSubmission) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{117} + return fileDescriptor_9198ee693835762e, []int{123} } func (m *AccessReviewSubmission) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8430,7 +8707,7 @@ func (m *ThresholdIndexSet) Reset() { *m = ThresholdIndexSet{} } func (m *ThresholdIndexSet) String() string { return proto.CompactTextString(m) } func (*ThresholdIndexSet) ProtoMessage() {} func (*ThresholdIndexSet) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{118} + return fileDescriptor_9198ee693835762e, []int{124} } func (m *ThresholdIndexSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8473,7 +8750,7 @@ func (m *ThresholdIndexSets) Reset() { *m = ThresholdIndexSets{} } func (m *ThresholdIndexSets) String() string { return proto.CompactTextString(m) } func (*ThresholdIndexSets) ProtoMessage() {} func (*ThresholdIndexSets) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{119} + return fileDescriptor_9198ee693835762e, []int{125} } func (m *ThresholdIndexSets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8585,7 +8862,7 @@ func (m *AccessRequestSpecV3) Reset() { *m = AccessRequestSpecV3{} } func (m *AccessRequestSpecV3) String() string { return proto.CompactTextString(m) } func (*AccessRequestSpecV3) ProtoMessage() {} func (*AccessRequestSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{120} + return fileDescriptor_9198ee693835762e, []int{126} } func (m *AccessRequestSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8642,7 +8919,7 @@ func (m *AccessRequestFilter) Reset() { *m = AccessRequestFilter{} } func (m *AccessRequestFilter) String() string { return proto.CompactTextString(m) } func (*AccessRequestFilter) ProtoMessage() {} func (*AccessRequestFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{121} + return fileDescriptor_9198ee693835762e, []int{127} } func (m *AccessRequestFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8698,7 +8975,7 @@ func (m *AccessCapabilities) Reset() { *m = AccessCapabilities{} } func (m *AccessCapabilities) String() string { return proto.CompactTextString(m) } func (*AccessCapabilities) ProtoMessage() {} func (*AccessCapabilities) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{122} + return fileDescriptor_9198ee693835762e, []int{128} } func (m *AccessCapabilities) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8756,7 +9033,7 @@ func (m *AccessCapabilitiesRequest) Reset() { *m = AccessCapabilitiesReq func (m *AccessCapabilitiesRequest) String() string { return proto.CompactTextString(m) } func (*AccessCapabilitiesRequest) ProtoMessage() {} func (*AccessCapabilitiesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{123} + return fileDescriptor_9198ee693835762e, []int{129} } func (m *AccessCapabilitiesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8802,7 +9079,7 @@ func (m *RequestKubernetesResource) Reset() { *m = RequestKubernetesReso func (m *RequestKubernetesResource) String() string { return proto.CompactTextString(m) } func (*RequestKubernetesResource) ProtoMessage() {} func (*RequestKubernetesResource) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{124} + return fileDescriptor_9198ee693835762e, []int{130} } func (m *RequestKubernetesResource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8855,7 +9132,7 @@ func (m *ResourceID) Reset() { *m = ResourceID{} } func (m *ResourceID) String() string { return proto.CompactTextString(m) } func (*ResourceID) ProtoMessage() {} func (*ResourceID) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{125} + return fileDescriptor_9198ee693835762e, []int{131} } func (m *ResourceID) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8904,7 +9181,7 @@ type PluginDataV3 struct { func (m *PluginDataV3) Reset() { *m = PluginDataV3{} } func (*PluginDataV3) ProtoMessage() {} func (*PluginDataV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{126} + return fileDescriptor_9198ee693835762e, []int{132} } func (m *PluginDataV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8947,7 +9224,7 @@ func (m *PluginDataEntry) Reset() { *m = PluginDataEntry{} } func (m *PluginDataEntry) String() string { return proto.CompactTextString(m) } func (*PluginDataEntry) ProtoMessage() {} func (*PluginDataEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{127} + return fileDescriptor_9198ee693835762e, []int{133} } func (m *PluginDataEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -8989,7 +9266,7 @@ func (m *PluginDataSpecV3) Reset() { *m = PluginDataSpecV3{} } func (m *PluginDataSpecV3) String() string { return proto.CompactTextString(m) } func (*PluginDataSpecV3) ProtoMessage() {} func (*PluginDataSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{128} + return fileDescriptor_9198ee693835762e, []int{134} } func (m *PluginDataSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9036,7 +9313,7 @@ func (m *PluginDataFilter) Reset() { *m = PluginDataFilter{} } func (m *PluginDataFilter) String() string { return proto.CompactTextString(m) } func (*PluginDataFilter) ProtoMessage() {} func (*PluginDataFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{129} + return fileDescriptor_9198ee693835762e, []int{135} } func (m *PluginDataFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9087,7 +9364,7 @@ func (m *PluginDataUpdateParams) Reset() { *m = PluginDataUpdateParams{} func (m *PluginDataUpdateParams) String() string { return proto.CompactTextString(m) } func (*PluginDataUpdateParams) ProtoMessage() {} func (*PluginDataUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{130} + return fileDescriptor_9198ee693835762e, []int{136} } func (m *PluginDataUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9131,7 +9408,7 @@ func (m *RoleFilter) Reset() { *m = RoleFilter{} } func (m *RoleFilter) String() string { return proto.CompactTextString(m) } func (*RoleFilter) ProtoMessage() {} func (*RoleFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{131} + return fileDescriptor_9198ee693835762e, []int{137} } func (m *RoleFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9181,7 +9458,7 @@ type RoleV6 struct { func (m *RoleV6) Reset() { *m = RoleV6{} } func (*RoleV6) ProtoMessage() {} func (*RoleV6) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{132} + return fileDescriptor_9198ee693835762e, []int{138} } func (m *RoleV6) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9228,7 +9505,7 @@ func (m *RoleSpecV6) Reset() { *m = RoleSpecV6{} } func (m *RoleSpecV6) String() string { return proto.CompactTextString(m) } func (*RoleSpecV6) ProtoMessage() {} func (*RoleSpecV6) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{133} + return fileDescriptor_9198ee693835762e, []int{139} } func (m *RoleSpecV6) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9269,7 +9546,7 @@ func (m *SSHLocalPortForwarding) Reset() { *m = SSHLocalPortForwarding{} func (m *SSHLocalPortForwarding) String() string { return proto.CompactTextString(m) } func (*SSHLocalPortForwarding) ProtoMessage() {} func (*SSHLocalPortForwarding) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{134} + return fileDescriptor_9198ee693835762e, []int{140} } func (m *SSHLocalPortForwarding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9310,7 +9587,7 @@ func (m *SSHRemotePortForwarding) Reset() { *m = SSHRemotePortForwarding func (m *SSHRemotePortForwarding) String() string { return proto.CompactTextString(m) } func (*SSHRemotePortForwarding) ProtoMessage() {} func (*SSHRemotePortForwarding) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{135} + return fileDescriptor_9198ee693835762e, []int{141} } func (m *SSHRemotePortForwarding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9354,7 +9631,7 @@ func (m *SSHPortForwarding) Reset() { *m = SSHPortForwarding{} } func (m *SSHPortForwarding) String() string { return proto.CompactTextString(m) } func (*SSHPortForwarding) ProtoMessage() {} func (*SSHPortForwarding) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{136} + return fileDescriptor_9198ee693835762e, []int{142} } func (m *SSHPortForwarding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9486,7 +9763,7 @@ func (m *RoleOptions) Reset() { *m = RoleOptions{} } func (m *RoleOptions) String() string { return proto.CompactTextString(m) } func (*RoleOptions) ProtoMessage() {} func (*RoleOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{137} + return fileDescriptor_9198ee693835762e, []int{143} } func (m *RoleOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9532,7 +9809,7 @@ func (m *RecordSession) Reset() { *m = RecordSession{} } func (m *RecordSession) String() string { return proto.CompactTextString(m) } func (*RecordSession) ProtoMessage() {} func (*RecordSession) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{138} + return fileDescriptor_9198ee693835762e, []int{144} } func (m *RecordSession) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9584,7 +9861,7 @@ func (m *CertExtension) Reset() { *m = CertExtension{} } func (m *CertExtension) String() string { return proto.CompactTextString(m) } func (*CertExtension) ProtoMessage() {} func (*CertExtension) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{139} + return fileDescriptor_9198ee693835762e, []int{145} } func (m *CertExtension) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9731,7 +10008,7 @@ func (m *RoleConditions) Reset() { *m = RoleConditions{} } func (m *RoleConditions) String() string { return proto.CompactTextString(m) } func (*RoleConditions) ProtoMessage() {} func (*RoleConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{140} + return fileDescriptor_9198ee693835762e, []int{146} } func (m *RoleConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9774,7 +10051,7 @@ func (m *IdentityCenterAccountAssignment) Reset() { *m = IdentityCenterA func (m *IdentityCenterAccountAssignment) String() string { return proto.CompactTextString(m) } func (*IdentityCenterAccountAssignment) ProtoMessage() {} func (*IdentityCenterAccountAssignment) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{141} + return fileDescriptor_9198ee693835762e, []int{147} } func (m *IdentityCenterAccountAssignment) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9815,7 +10092,7 @@ func (m *GitHubPermission) Reset() { *m = GitHubPermission{} } func (m *GitHubPermission) String() string { return proto.CompactTextString(m) } func (*GitHubPermission) ProtoMessage() {} func (*GitHubPermission) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{142} + return fileDescriptor_9198ee693835762e, []int{148} } func (m *GitHubPermission) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9860,7 +10137,7 @@ func (m *MCPPermissions) Reset() { *m = MCPPermissions{} } func (m *MCPPermissions) String() string { return proto.CompactTextString(m) } func (*MCPPermissions) ProtoMessage() {} func (*MCPPermissions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{143} + return fileDescriptor_9198ee693835762e, []int{149} } func (m *MCPPermissions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9936,7 +10213,7 @@ func (m *SPIFFERoleCondition) Reset() { *m = SPIFFERoleCondition{} } func (m *SPIFFERoleCondition) String() string { return proto.CompactTextString(m) } func (*SPIFFERoleCondition) ProtoMessage() {} func (*SPIFFERoleCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{144} + return fileDescriptor_9198ee693835762e, []int{150} } func (m *SPIFFERoleCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -9980,7 +10257,7 @@ func (m *DatabasePermission) Reset() { *m = DatabasePermission{} } func (m *DatabasePermission) String() string { return proto.CompactTextString(m) } func (*DatabasePermission) ProtoMessage() {} func (*DatabasePermission) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{145} + return fileDescriptor_9198ee693835762e, []int{151} } func (m *DatabasePermission) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10033,7 +10310,7 @@ func (m *KubernetesResource) Reset() { *m = KubernetesResource{} } func (m *KubernetesResource) String() string { return proto.CompactTextString(m) } func (*KubernetesResource) ProtoMessage() {} func (*KubernetesResource) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{146} + return fileDescriptor_9198ee693835762e, []int{152} } func (m *KubernetesResource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10086,7 +10363,7 @@ func (m *SessionRequirePolicy) Reset() { *m = SessionRequirePolicy{} } func (m *SessionRequirePolicy) String() string { return proto.CompactTextString(m) } func (*SessionRequirePolicy) ProtoMessage() {} func (*SessionRequirePolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{147} + return fileDescriptor_9198ee693835762e, []int{153} } func (m *SessionRequirePolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10134,7 +10411,7 @@ func (m *SessionJoinPolicy) Reset() { *m = SessionJoinPolicy{} } func (m *SessionJoinPolicy) String() string { return proto.CompactTextString(m) } func (*SessionJoinPolicy) ProtoMessage() {} func (*SessionJoinPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{148} + return fileDescriptor_9198ee693835762e, []int{154} } func (m *SessionJoinPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10210,7 +10487,7 @@ func (m *AccessRequestConditions) Reset() { *m = AccessRequestConditions func (m *AccessRequestConditions) String() string { return proto.CompactTextString(m) } func (*AccessRequestConditions) ProtoMessage() {} func (*AccessRequestConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{149} + return fileDescriptor_9198ee693835762e, []int{155} } func (m *AccessRequestConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10256,7 +10533,7 @@ func (m *AccessRequestConditionsReason) Reset() { *m = AccessRequestCond func (m *AccessRequestConditionsReason) String() string { return proto.CompactTextString(m) } func (*AccessRequestConditionsReason) ProtoMessage() {} func (*AccessRequestConditionsReason) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{150} + return fileDescriptor_9198ee693835762e, []int{156} } func (m *AccessRequestConditionsReason) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10309,7 +10586,7 @@ func (m *AccessReviewConditions) Reset() { *m = AccessReviewConditions{} func (m *AccessReviewConditions) String() string { return proto.CompactTextString(m) } func (*AccessReviewConditions) ProtoMessage() {} func (*AccessReviewConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{151} + return fileDescriptor_9198ee693835762e, []int{157} } func (m *AccessReviewConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10351,7 +10628,7 @@ func (m *AccessRequestAllowedPromotion) Reset() { *m = AccessRequestAllo func (m *AccessRequestAllowedPromotion) String() string { return proto.CompactTextString(m) } func (*AccessRequestAllowedPromotion) ProtoMessage() {} func (*AccessRequestAllowedPromotion) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{152} + return fileDescriptor_9198ee693835762e, []int{158} } func (m *AccessRequestAllowedPromotion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10394,7 +10671,7 @@ func (m *AccessRequestAllowedPromotions) Reset() { *m = AccessRequestAll func (m *AccessRequestAllowedPromotions) String() string { return proto.CompactTextString(m) } func (*AccessRequestAllowedPromotions) ProtoMessage() {} func (*AccessRequestAllowedPromotions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{153} + return fileDescriptor_9198ee693835762e, []int{159} } func (m *AccessRequestAllowedPromotions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10435,7 +10712,7 @@ func (m *ResourceIDList) Reset() { *m = ResourceIDList{} } func (m *ResourceIDList) String() string { return proto.CompactTextString(m) } func (*ResourceIDList) ProtoMessage() {} func (*ResourceIDList) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{154} + return fileDescriptor_9198ee693835762e, []int{160} } func (m *ResourceIDList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10488,7 +10765,7 @@ func (m *LongTermResourceGrouping) Reset() { *m = LongTermResourceGroupi func (m *LongTermResourceGrouping) String() string { return proto.CompactTextString(m) } func (*LongTermResourceGrouping) ProtoMessage() {} func (*LongTermResourceGrouping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{155} + return fileDescriptor_9198ee693835762e, []int{161} } func (m *LongTermResourceGrouping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10534,7 +10811,7 @@ func (m *ClaimMapping) Reset() { *m = ClaimMapping{} } func (m *ClaimMapping) String() string { return proto.CompactTextString(m) } func (*ClaimMapping) ProtoMessage() {} func (*ClaimMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{156} + return fileDescriptor_9198ee693835762e, []int{162} } func (m *ClaimMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10580,7 +10857,7 @@ func (m *TraitMapping) Reset() { *m = TraitMapping{} } func (m *TraitMapping) String() string { return proto.CompactTextString(m) } func (*TraitMapping) ProtoMessage() {} func (*TraitMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{157} + return fileDescriptor_9198ee693835762e, []int{163} } func (m *TraitMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10629,7 +10906,7 @@ func (m *Rule) Reset() { *m = Rule{} } func (m *Rule) String() string { return proto.CompactTextString(m) } func (*Rule) ProtoMessage() {} func (*Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{158} + return fileDescriptor_9198ee693835762e, []int{164} } func (m *Rule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10677,7 +10954,7 @@ func (m *ImpersonateConditions) Reset() { *m = ImpersonateConditions{} } func (m *ImpersonateConditions) String() string { return proto.CompactTextString(m) } func (*ImpersonateConditions) ProtoMessage() {} func (*ImpersonateConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{159} + return fileDescriptor_9198ee693835762e, []int{165} } func (m *ImpersonateConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10719,7 +10996,7 @@ func (m *BoolValue) Reset() { *m = BoolValue{} } func (m *BoolValue) String() string { return proto.CompactTextString(m) } func (*BoolValue) ProtoMessage() {} func (*BoolValue) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{160} + return fileDescriptor_9198ee693835762e, []int{166} } func (m *BoolValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10763,7 +11040,7 @@ func (m *UserFilter) Reset() { *m = UserFilter{} } func (m *UserFilter) String() string { return proto.CompactTextString(m) } func (*UserFilter) ProtoMessage() {} func (*UserFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{161} + return fileDescriptor_9198ee693835762e, []int{167} } func (m *UserFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10814,7 +11091,7 @@ type UserV2 struct { func (m *UserV2) Reset() { *m = UserV2{} } func (*UserV2) ProtoMessage() {} func (*UserV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{162} + return fileDescriptor_9198ee693835762e, []int{168} } func (m *UserV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10863,7 +11140,7 @@ func (m *UserStatusV2) Reset() { *m = UserStatusV2{} } func (m *UserStatusV2) String() string { return proto.CompactTextString(m) } func (*UserStatusV2) ProtoMessage() {} func (*UserStatusV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{163} + return fileDescriptor_9198ee693835762e, []int{169} } func (m *UserStatusV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10937,7 +11214,7 @@ func (m *UserSpecV2) Reset() { *m = UserSpecV2{} } func (m *UserSpecV2) String() string { return proto.CompactTextString(m) } func (*UserSpecV2) ProtoMessage() {} func (*UserSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{164} + return fileDescriptor_9198ee693835762e, []int{170} } func (m *UserSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -10987,7 +11264,7 @@ type ExternalIdentity struct { func (m *ExternalIdentity) Reset() { *m = ExternalIdentity{} } func (*ExternalIdentity) ProtoMessage() {} func (*ExternalIdentity) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{165} + return fileDescriptor_9198ee693835762e, []int{171} } func (m *ExternalIdentity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11035,7 +11312,7 @@ func (m *LoginStatus) Reset() { *m = LoginStatus{} } func (m *LoginStatus) String() string { return proto.CompactTextString(m) } func (*LoginStatus) ProtoMessage() {} func (*LoginStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{166} + return fileDescriptor_9198ee693835762e, []int{172} } func (m *LoginStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11080,7 +11357,7 @@ type CreatedBy struct { func (m *CreatedBy) Reset() { *m = CreatedBy{} } func (*CreatedBy) ProtoMessage() {} func (*CreatedBy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{167} + return fileDescriptor_9198ee693835762e, []int{173} } func (m *CreatedBy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11129,7 +11406,7 @@ func (m *LocalAuthSecrets) Reset() { *m = LocalAuthSecrets{} } func (m *LocalAuthSecrets) String() string { return proto.CompactTextString(m) } func (*LocalAuthSecrets) ProtoMessage() {} func (*LocalAuthSecrets) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{168} + return fileDescriptor_9198ee693835762e, []int{174} } func (m *LocalAuthSecrets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11186,7 +11463,7 @@ func (m *MFADevice) Reset() { *m = MFADevice{} } func (m *MFADevice) String() string { return proto.CompactTextString(m) } func (*MFADevice) ProtoMessage() {} func (*MFADevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{169} + return fileDescriptor_9198ee693835762e, []int{175} } func (m *MFADevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11296,7 +11573,7 @@ func (m *TOTPDevice) Reset() { *m = TOTPDevice{} } func (m *TOTPDevice) String() string { return proto.CompactTextString(m) } func (*TOTPDevice) ProtoMessage() {} func (*TOTPDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{170} + return fileDescriptor_9198ee693835762e, []int{176} } func (m *TOTPDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11342,7 +11619,7 @@ func (m *U2FDevice) Reset() { *m = U2FDevice{} } func (m *U2FDevice) String() string { return proto.CompactTextString(m) } func (*U2FDevice) ProtoMessage() {} func (*U2FDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{171} + return fileDescriptor_9198ee693835762e, []int{177} } func (m *U2FDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11424,7 +11701,7 @@ func (m *WebauthnDevice) Reset() { *m = WebauthnDevice{} } func (m *WebauthnDevice) String() string { return proto.CompactTextString(m) } func (*WebauthnDevice) ProtoMessage() {} func (*WebauthnDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{172} + return fileDescriptor_9198ee693835762e, []int{178} } func (m *WebauthnDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11470,7 +11747,7 @@ func (m *SSOMFADevice) Reset() { *m = SSOMFADevice{} } func (m *SSOMFADevice) String() string { return proto.CompactTextString(m) } func (*SSOMFADevice) ProtoMessage() {} func (*SSOMFADevice) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{173} + return fileDescriptor_9198ee693835762e, []int{179} } func (m *SSOMFADevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11513,7 +11790,7 @@ func (m *WebauthnLocalAuth) Reset() { *m = WebauthnLocalAuth{} } func (m *WebauthnLocalAuth) String() string { return proto.CompactTextString(m) } func (*WebauthnLocalAuth) ProtoMessage() {} func (*WebauthnLocalAuth) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{174} + return fileDescriptor_9198ee693835762e, []int{180} } func (m *WebauthnLocalAuth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11559,7 +11836,7 @@ func (m *ConnectorRef) Reset() { *m = ConnectorRef{} } func (m *ConnectorRef) String() string { return proto.CompactTextString(m) } func (*ConnectorRef) ProtoMessage() {} func (*ConnectorRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{175} + return fileDescriptor_9198ee693835762e, []int{181} } func (m *ConnectorRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11601,7 +11878,7 @@ func (m *UserRef) Reset() { *m = UserRef{} } func (m *UserRef) String() string { return proto.CompactTextString(m) } func (*UserRef) ProtoMessage() {} func (*UserRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{176} + return fileDescriptor_9198ee693835762e, []int{182} } func (m *UserRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11651,7 +11928,7 @@ func (m *ReverseTunnelV2) Reset() { *m = ReverseTunnelV2{} } func (m *ReverseTunnelV2) String() string { return proto.CompactTextString(m) } func (*ReverseTunnelV2) ProtoMessage() {} func (*ReverseTunnelV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{177} + return fileDescriptor_9198ee693835762e, []int{183} } func (m *ReverseTunnelV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11698,7 +11975,7 @@ func (m *ReverseTunnelSpecV2) Reset() { *m = ReverseTunnelSpecV2{} } func (m *ReverseTunnelSpecV2) String() string { return proto.CompactTextString(m) } func (*ReverseTunnelSpecV2) ProtoMessage() {} func (*ReverseTunnelSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{178} + return fileDescriptor_9198ee693835762e, []int{184} } func (m *ReverseTunnelSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11747,7 +12024,7 @@ type TunnelConnectionV2 struct { func (m *TunnelConnectionV2) Reset() { *m = TunnelConnectionV2{} } func (*TunnelConnectionV2) ProtoMessage() {} func (*TunnelConnectionV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{179} + return fileDescriptor_9198ee693835762e, []int{185} } func (m *TunnelConnectionV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11795,7 +12072,7 @@ func (m *TunnelConnectionSpecV2) Reset() { *m = TunnelConnectionSpecV2{} func (m *TunnelConnectionSpecV2) String() string { return proto.CompactTextString(m) } func (*TunnelConnectionSpecV2) ProtoMessage() {} func (*TunnelConnectionSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{180} + return fileDescriptor_9198ee693835762e, []int{186} } func (m *TunnelConnectionSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11843,7 +12120,7 @@ func (m *SemaphoreFilter) Reset() { *m = SemaphoreFilter{} } func (m *SemaphoreFilter) String() string { return proto.CompactTextString(m) } func (*SemaphoreFilter) ProtoMessage() {} func (*SemaphoreFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{181} + return fileDescriptor_9198ee693835762e, []int{187} } func (m *SemaphoreFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11894,7 +12171,7 @@ func (m *AcquireSemaphoreRequest) Reset() { *m = AcquireSemaphoreRequest func (m *AcquireSemaphoreRequest) String() string { return proto.CompactTextString(m) } func (*AcquireSemaphoreRequest) ProtoMessage() {} func (*AcquireSemaphoreRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{182} + return fileDescriptor_9198ee693835762e, []int{188} } func (m *AcquireSemaphoreRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11942,7 +12219,7 @@ func (m *SemaphoreLease) Reset() { *m = SemaphoreLease{} } func (m *SemaphoreLease) String() string { return proto.CompactTextString(m) } func (*SemaphoreLease) ProtoMessage() {} func (*SemaphoreLease) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{183} + return fileDescriptor_9198ee693835762e, []int{189} } func (m *SemaphoreLease) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11988,7 +12265,7 @@ func (m *SemaphoreLeaseRef) Reset() { *m = SemaphoreLeaseRef{} } func (m *SemaphoreLeaseRef) String() string { return proto.CompactTextString(m) } func (*SemaphoreLeaseRef) ProtoMessage() {} func (*SemaphoreLeaseRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{184} + return fileDescriptor_9198ee693835762e, []int{190} } func (m *SemaphoreLeaseRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12037,7 +12314,7 @@ type SemaphoreV3 struct { func (m *SemaphoreV3) Reset() { *m = SemaphoreV3{} } func (*SemaphoreV3) ProtoMessage() {} func (*SemaphoreV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{185} + return fileDescriptor_9198ee693835762e, []int{191} } func (m *SemaphoreV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12079,7 +12356,7 @@ func (m *SemaphoreSpecV3) Reset() { *m = SemaphoreSpecV3{} } func (m *SemaphoreSpecV3) String() string { return proto.CompactTextString(m) } func (*SemaphoreSpecV3) ProtoMessage() {} func (*SemaphoreSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{186} + return fileDescriptor_9198ee693835762e, []int{192} } func (m *SemaphoreSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12128,7 +12405,7 @@ type WebSessionV2 struct { func (m *WebSessionV2) Reset() { *m = WebSessionV2{} } func (*WebSessionV2) ProtoMessage() {} func (*WebSessionV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{187} + return fileDescriptor_9198ee693835762e, []int{193} } func (m *WebSessionV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12213,7 +12490,7 @@ func (m *WebSessionSpecV2) Reset() { *m = WebSessionSpecV2{} } func (m *WebSessionSpecV2) String() string { return proto.CompactTextString(m) } func (*WebSessionSpecV2) ProtoMessage() {} func (*WebSessionSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{188} + return fileDescriptor_9198ee693835762e, []int{194} } func (m *WebSessionSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12258,7 +12535,7 @@ func (m *DeviceWebToken) Reset() { *m = DeviceWebToken{} } func (m *DeviceWebToken) String() string { return proto.CompactTextString(m) } func (*DeviceWebToken) ProtoMessage() {} func (*DeviceWebToken) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{189} + return fileDescriptor_9198ee693835762e, []int{195} } func (m *DeviceWebToken) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12300,7 +12577,7 @@ func (m *WebSessionFilter) Reset() { *m = WebSessionFilter{} } func (m *WebSessionFilter) String() string { return proto.CompactTextString(m) } func (*WebSessionFilter) ProtoMessage() {} func (*WebSessionFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{190} + return fileDescriptor_9198ee693835762e, []int{196} } func (m *WebSessionFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12371,7 +12648,7 @@ func (m *SAMLSessionData) Reset() { *m = SAMLSessionData{} } func (m *SAMLSessionData) String() string { return proto.CompactTextString(m) } func (*SAMLSessionData) ProtoMessage() {} func (*SAMLSessionData) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{191} + return fileDescriptor_9198ee693835762e, []int{197} } func (m *SAMLSessionData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12420,7 +12697,7 @@ func (m *SAMLAttribute) Reset() { *m = SAMLAttribute{} } func (m *SAMLAttribute) String() string { return proto.CompactTextString(m) } func (*SAMLAttribute) ProtoMessage() {} func (*SAMLAttribute) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{192} + return fileDescriptor_9198ee693835762e, []int{198} } func (m *SAMLAttribute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12467,7 +12744,7 @@ func (m *SAMLAttributeValue) Reset() { *m = SAMLAttributeValue{} } func (m *SAMLAttributeValue) String() string { return proto.CompactTextString(m) } func (*SAMLAttributeValue) ProtoMessage() {} func (*SAMLAttributeValue) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{193} + return fileDescriptor_9198ee693835762e, []int{199} } func (m *SAMLAttributeValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12518,7 +12795,7 @@ func (m *SAMLNameID) Reset() { *m = SAMLNameID{} } func (m *SAMLNameID) String() string { return proto.CompactTextString(m) } func (*SAMLNameID) ProtoMessage() {} func (*SAMLNameID) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{194} + return fileDescriptor_9198ee693835762e, []int{200} } func (m *SAMLNameID) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12567,7 +12844,7 @@ type RemoteClusterV3 struct { func (m *RemoteClusterV3) Reset() { *m = RemoteClusterV3{} } func (*RemoteClusterV3) ProtoMessage() {} func (*RemoteClusterV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{195} + return fileDescriptor_9198ee693835762e, []int{201} } func (m *RemoteClusterV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12611,7 +12888,7 @@ func (m *RemoteClusterStatusV3) Reset() { *m = RemoteClusterStatusV3{} } func (m *RemoteClusterStatusV3) String() string { return proto.CompactTextString(m) } func (*RemoteClusterStatusV3) ProtoMessage() {} func (*RemoteClusterStatusV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{196} + return fileDescriptor_9198ee693835762e, []int{202} } func (m *RemoteClusterStatusV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12661,7 +12938,7 @@ func (m *KubernetesCluster) Reset() { *m = KubernetesCluster{} } func (m *KubernetesCluster) String() string { return proto.CompactTextString(m) } func (*KubernetesCluster) ProtoMessage() {} func (*KubernetesCluster) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{197} + return fileDescriptor_9198ee693835762e, []int{203} } func (m *KubernetesCluster) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12710,7 +12987,7 @@ type KubernetesClusterV3 struct { func (m *KubernetesClusterV3) Reset() { *m = KubernetesClusterV3{} } func (*KubernetesClusterV3) ProtoMessage() {} func (*KubernetesClusterV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{198} + return fileDescriptor_9198ee693835762e, []int{204} } func (m *KubernetesClusterV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12761,7 +13038,7 @@ func (m *KubernetesClusterSpecV3) Reset() { *m = KubernetesClusterSpecV3 func (m *KubernetesClusterSpecV3) String() string { return proto.CompactTextString(m) } func (*KubernetesClusterSpecV3) ProtoMessage() {} func (*KubernetesClusterSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{199} + return fileDescriptor_9198ee693835762e, []int{205} } func (m *KubernetesClusterSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12809,7 +13086,7 @@ func (m *KubeAzure) Reset() { *m = KubeAzure{} } func (m *KubeAzure) String() string { return proto.CompactTextString(m) } func (*KubeAzure) ProtoMessage() {} func (*KubeAzure) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{200} + return fileDescriptor_9198ee693835762e, []int{206} } func (m *KubeAzure) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12855,7 +13132,7 @@ func (m *KubeAWS) Reset() { *m = KubeAWS{} } func (m *KubeAWS) String() string { return proto.CompactTextString(m) } func (*KubeAWS) ProtoMessage() {} func (*KubeAWS) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{201} + return fileDescriptor_9198ee693835762e, []int{207} } func (m *KubeAWS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12901,7 +13178,7 @@ func (m *KubeGCP) Reset() { *m = KubeGCP{} } func (m *KubeGCP) String() string { return proto.CompactTextString(m) } func (*KubeGCP) ProtoMessage() {} func (*KubeGCP) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{202} + return fileDescriptor_9198ee693835762e, []int{208} } func (m *KubeGCP) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12943,7 +13220,7 @@ func (m *KubernetesClusterV3List) Reset() { *m = KubernetesClusterV3List func (m *KubernetesClusterV3List) String() string { return proto.CompactTextString(m) } func (*KubernetesClusterV3List) ProtoMessage() {} func (*KubernetesClusterV3List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{203} + return fileDescriptor_9198ee693835762e, []int{209} } func (m *KubernetesClusterV3List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -12992,7 +13269,7 @@ type KubernetesServerV3 struct { func (m *KubernetesServerV3) Reset() { *m = KubernetesServerV3{} } func (*KubernetesServerV3) ProtoMessage() {} func (*KubernetesServerV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{204} + return fileDescriptor_9198ee693835762e, []int{210} } func (m *KubernetesServerV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13044,7 +13321,7 @@ func (m *KubernetesServerSpecV3) Reset() { *m = KubernetesServerSpecV3{} func (m *KubernetesServerSpecV3) String() string { return proto.CompactTextString(m) } func (*KubernetesServerSpecV3) ProtoMessage() {} func (*KubernetesServerSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{205} + return fileDescriptor_9198ee693835762e, []int{211} } func (m *KubernetesServerSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13096,7 +13373,7 @@ type WebTokenV3 struct { func (m *WebTokenV3) Reset() { *m = WebTokenV3{} } func (*WebTokenV3) ProtoMessage() {} func (*WebTokenV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{206} + return fileDescriptor_9198ee693835762e, []int{212} } func (m *WebTokenV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13140,7 +13417,7 @@ func (m *WebTokenSpecV3) Reset() { *m = WebTokenSpecV3{} } func (m *WebTokenSpecV3) String() string { return proto.CompactTextString(m) } func (*WebTokenSpecV3) ProtoMessage() {} func (*WebTokenSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{207} + return fileDescriptor_9198ee693835762e, []int{213} } func (m *WebTokenSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13184,7 +13461,7 @@ func (m *GetWebSessionRequest) Reset() { *m = GetWebSessionRequest{} } func (m *GetWebSessionRequest) String() string { return proto.CompactTextString(m) } func (*GetWebSessionRequest) ProtoMessage() {} func (*GetWebSessionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{208} + return fileDescriptor_9198ee693835762e, []int{214} } func (m *GetWebSessionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13228,7 +13505,7 @@ func (m *DeleteWebSessionRequest) Reset() { *m = DeleteWebSessionRequest func (m *DeleteWebSessionRequest) String() string { return proto.CompactTextString(m) } func (*DeleteWebSessionRequest) ProtoMessage() {} func (*DeleteWebSessionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{209} + return fileDescriptor_9198ee693835762e, []int{215} } func (m *DeleteWebSessionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13272,7 +13549,7 @@ func (m *GetWebTokenRequest) Reset() { *m = GetWebTokenRequest{} } func (m *GetWebTokenRequest) String() string { return proto.CompactTextString(m) } func (*GetWebTokenRequest) ProtoMessage() {} func (*GetWebTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{210} + return fileDescriptor_9198ee693835762e, []int{216} } func (m *GetWebTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13316,7 +13593,7 @@ func (m *DeleteWebTokenRequest) Reset() { *m = DeleteWebTokenRequest{} } func (m *DeleteWebTokenRequest) String() string { return proto.CompactTextString(m) } func (*DeleteWebTokenRequest) ProtoMessage() {} func (*DeleteWebTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{211} + return fileDescriptor_9198ee693835762e, []int{217} } func (m *DeleteWebTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13358,7 +13635,7 @@ func (m *ResourceRequest) Reset() { *m = ResourceRequest{} } func (m *ResourceRequest) String() string { return proto.CompactTextString(m) } func (*ResourceRequest) ProtoMessage() {} func (*ResourceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{212} + return fileDescriptor_9198ee693835762e, []int{218} } func (m *ResourceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13407,7 +13684,7 @@ func (m *ResourceWithSecretsRequest) Reset() { *m = ResourceWithSecretsR func (m *ResourceWithSecretsRequest) String() string { return proto.CompactTextString(m) } func (*ResourceWithSecretsRequest) ProtoMessage() {} func (*ResourceWithSecretsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{213} + return fileDescriptor_9198ee693835762e, []int{219} } func (m *ResourceWithSecretsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13454,7 +13731,7 @@ func (m *ResourcesWithSecretsRequest) Reset() { *m = ResourcesWithSecret func (m *ResourcesWithSecretsRequest) String() string { return proto.CompactTextString(m) } func (*ResourcesWithSecretsRequest) ProtoMessage() {} func (*ResourcesWithSecretsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{214} + return fileDescriptor_9198ee693835762e, []int{220} } func (m *ResourcesWithSecretsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13498,7 +13775,7 @@ func (m *ResourceInNamespaceRequest) Reset() { *m = ResourceInNamespaceR func (m *ResourceInNamespaceRequest) String() string { return proto.CompactTextString(m) } func (*ResourceInNamespaceRequest) ProtoMessage() {} func (*ResourceInNamespaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{215} + return fileDescriptor_9198ee693835762e, []int{221} } func (m *ResourceInNamespaceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13540,7 +13817,7 @@ func (m *ResourcesInNamespaceRequest) Reset() { *m = ResourcesInNamespac func (m *ResourcesInNamespaceRequest) String() string { return proto.CompactTextString(m) } func (*ResourcesInNamespaceRequest) ProtoMessage() {} func (*ResourcesInNamespaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{216} + return fileDescriptor_9198ee693835762e, []int{222} } func (m *ResourcesInNamespaceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13591,7 +13868,7 @@ func (m *OIDCConnectorV3) Reset() { *m = OIDCConnectorV3{} } func (m *OIDCConnectorV3) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorV3) ProtoMessage() {} func (*OIDCConnectorV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{217} + return fileDescriptor_9198ee693835762e, []int{223} } func (m *OIDCConnectorV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13633,7 +13910,7 @@ func (m *OIDCConnectorV3List) Reset() { *m = OIDCConnectorV3List{} } func (m *OIDCConnectorV3List) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorV3List) ProtoMessage() {} func (*OIDCConnectorV3List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{218} + return fileDescriptor_9198ee693835762e, []int{224} } func (m *OIDCConnectorV3List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13734,7 +14011,7 @@ func (m *OIDCConnectorSpecV3) Reset() { *m = OIDCConnectorSpecV3{} } func (m *OIDCConnectorSpecV3) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorSpecV3) ProtoMessage() {} func (*OIDCConnectorSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{219} + return fileDescriptor_9198ee693835762e, []int{225} } func (m *OIDCConnectorSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13793,7 +14070,7 @@ func (m *EntraIDGroupsProvider) Reset() { *m = EntraIDGroupsProvider{} } func (m *EntraIDGroupsProvider) String() string { return proto.CompactTextString(m) } func (*EntraIDGroupsProvider) ProtoMessage() {} func (*EntraIDGroupsProvider) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{220} + return fileDescriptor_9198ee693835762e, []int{226} } func (m *EntraIDGroupsProvider) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13835,7 +14112,7 @@ func (m *MaxAge) Reset() { *m = MaxAge{} } func (m *MaxAge) String() string { return proto.CompactTextString(m) } func (*MaxAge) ProtoMessage() {} func (*MaxAge) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{221} + return fileDescriptor_9198ee693835762e, []int{227} } func (m *MaxAge) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13880,7 +14157,7 @@ func (m *SSOClientRedirectSettings) Reset() { *m = SSOClientRedirectSett func (m *SSOClientRedirectSettings) String() string { return proto.CompactTextString(m) } func (*SSOClientRedirectSettings) ProtoMessage() {} func (*SSOClientRedirectSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{222} + return fileDescriptor_9198ee693835762e, []int{228} } func (m *SSOClientRedirectSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -13943,7 +14220,7 @@ func (m *OIDCConnectorMFASettings) Reset() { *m = OIDCConnectorMFASettin func (m *OIDCConnectorMFASettings) String() string { return proto.CompactTextString(m) } func (*OIDCConnectorMFASettings) ProtoMessage() {} func (*OIDCConnectorMFASettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{223} + return fileDescriptor_9198ee693835762e, []int{229} } func (m *OIDCConnectorMFASettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14038,7 +14315,7 @@ func (m *OIDCAuthRequest) Reset() { *m = OIDCAuthRequest{} } func (m *OIDCAuthRequest) String() string { return proto.CompactTextString(m) } func (*OIDCAuthRequest) ProtoMessage() {} func (*OIDCAuthRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{224} + return fileDescriptor_9198ee693835762e, []int{230} } func (m *OIDCAuthRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14089,7 +14366,7 @@ func (m *SAMLConnectorV2) Reset() { *m = SAMLConnectorV2{} } func (m *SAMLConnectorV2) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorV2) ProtoMessage() {} func (*SAMLConnectorV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{225} + return fileDescriptor_9198ee693835762e, []int{231} } func (m *SAMLConnectorV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14131,7 +14408,7 @@ func (m *SAMLConnectorV2List) Reset() { *m = SAMLConnectorV2List{} } func (m *SAMLConnectorV2List) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorV2List) ProtoMessage() {} func (*SAMLConnectorV2List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{226} + return fileDescriptor_9198ee693835762e, []int{232} } func (m *SAMLConnectorV2List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14224,7 +14501,7 @@ func (m *SAMLConnectorSpecV2) Reset() { *m = SAMLConnectorSpecV2{} } func (m *SAMLConnectorSpecV2) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorSpecV2) ProtoMessage() {} func (*SAMLConnectorSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{227} + return fileDescriptor_9198ee693835762e, []int{233} } func (m *SAMLConnectorSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14283,7 +14560,7 @@ func (m *SAMLConnectorMFASettings) Reset() { *m = SAMLConnectorMFASettin func (m *SAMLConnectorMFASettings) String() string { return proto.CompactTextString(m) } func (*SAMLConnectorMFASettings) ProtoMessage() {} func (*SAMLConnectorMFASettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{228} + return fileDescriptor_9198ee693835762e, []int{234} } func (m *SAMLConnectorMFASettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14376,7 +14653,7 @@ func (m *SAMLAuthRequest) Reset() { *m = SAMLAuthRequest{} } func (m *SAMLAuthRequest) String() string { return proto.CompactTextString(m) } func (*SAMLAuthRequest) ProtoMessage() {} func (*SAMLAuthRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{229} + return fileDescriptor_9198ee693835762e, []int{235} } func (m *SAMLAuthRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14422,7 +14699,7 @@ func (m *AttributeMapping) Reset() { *m = AttributeMapping{} } func (m *AttributeMapping) String() string { return proto.CompactTextString(m) } func (*AttributeMapping) ProtoMessage() {} func (*AttributeMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{230} + return fileDescriptor_9198ee693835762e, []int{236} } func (m *AttributeMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14467,7 +14744,7 @@ func (m *AsymmetricKeyPair) Reset() { *m = AsymmetricKeyPair{} } func (m *AsymmetricKeyPair) String() string { return proto.CompactTextString(m) } func (*AsymmetricKeyPair) ProtoMessage() {} func (*AsymmetricKeyPair) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{231} + return fileDescriptor_9198ee693835762e, []int{237} } func (m *AsymmetricKeyPair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14518,7 +14795,7 @@ func (m *GithubConnectorV3) Reset() { *m = GithubConnectorV3{} } func (m *GithubConnectorV3) String() string { return proto.CompactTextString(m) } func (*GithubConnectorV3) ProtoMessage() {} func (*GithubConnectorV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{232} + return fileDescriptor_9198ee693835762e, []int{238} } func (m *GithubConnectorV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14560,7 +14837,7 @@ func (m *GithubConnectorV3List) Reset() { *m = GithubConnectorV3List{} } func (m *GithubConnectorV3List) String() string { return proto.CompactTextString(m) } func (*GithubConnectorV3List) ProtoMessage() {} func (*GithubConnectorV3List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{233} + return fileDescriptor_9198ee693835762e, []int{239} } func (m *GithubConnectorV3List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14626,7 +14903,7 @@ func (m *GithubConnectorSpecV3) Reset() { *m = GithubConnectorSpecV3{} } func (m *GithubConnectorSpecV3) String() string { return proto.CompactTextString(m) } func (*GithubConnectorSpecV3) ProtoMessage() {} func (*GithubConnectorSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{234} + return fileDescriptor_9198ee693835762e, []int{240} } func (m *GithubConnectorSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14715,7 +14992,7 @@ func (m *GithubAuthRequest) Reset() { *m = GithubAuthRequest{} } func (m *GithubAuthRequest) String() string { return proto.CompactTextString(m) } func (*GithubAuthRequest) ProtoMessage() {} func (*GithubAuthRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{235} + return fileDescriptor_9198ee693835762e, []int{241} } func (m *GithubAuthRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14759,7 +15036,7 @@ func (m *SSOWarnings) Reset() { *m = SSOWarnings{} } func (m *SSOWarnings) String() string { return proto.CompactTextString(m) } func (*SSOWarnings) ProtoMessage() {} func (*SSOWarnings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{236} + return fileDescriptor_9198ee693835762e, []int{242} } func (m *SSOWarnings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14815,7 +15092,7 @@ func (m *CreateUserParams) Reset() { *m = CreateUserParams{} } func (m *CreateUserParams) String() string { return proto.CompactTextString(m) } func (*CreateUserParams) ProtoMessage() {} func (*CreateUserParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{237} + return fileDescriptor_9198ee693835762e, []int{243} } func (m *CreateUserParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14900,7 +15177,7 @@ func (m *SSODiagnosticInfo) Reset() { *m = SSODiagnosticInfo{} } func (m *SSODiagnosticInfo) String() string { return proto.CompactTextString(m) } func (*SSODiagnosticInfo) ProtoMessage() {} func (*SSODiagnosticInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{238} + return fileDescriptor_9198ee693835762e, []int{244} } func (m *SSODiagnosticInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14944,7 +15221,7 @@ func (m *GithubTokenInfo) Reset() { *m = GithubTokenInfo{} } func (m *GithubTokenInfo) String() string { return proto.CompactTextString(m) } func (*GithubTokenInfo) ProtoMessage() {} func (*GithubTokenInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{239} + return fileDescriptor_9198ee693835762e, []int{245} } func (m *GithubTokenInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -14995,7 +15272,7 @@ func (m *GithubClaims) Reset() { *m = GithubClaims{} } func (m *GithubClaims) String() string { return proto.CompactTextString(m) } func (*GithubClaims) ProtoMessage() {} func (*GithubClaims) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{240} + return fileDescriptor_9198ee693835762e, []int{246} } func (m *GithubClaims) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15047,7 +15324,7 @@ func (m *TeamMapping) Reset() { *m = TeamMapping{} } func (m *TeamMapping) String() string { return proto.CompactTextString(m) } func (*TeamMapping) ProtoMessage() {} func (*TeamMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{241} + return fileDescriptor_9198ee693835762e, []int{247} } func (m *TeamMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15093,7 +15370,7 @@ func (m *TeamRolesMapping) Reset() { *m = TeamRolesMapping{} } func (m *TeamRolesMapping) String() string { return proto.CompactTextString(m) } func (*TeamRolesMapping) ProtoMessage() {} func (*TeamRolesMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{242} + return fileDescriptor_9198ee693835762e, []int{248} } func (m *TeamRolesMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15143,7 +15420,7 @@ type TrustedClusterV2 struct { func (m *TrustedClusterV2) Reset() { *m = TrustedClusterV2{} } func (*TrustedClusterV2) ProtoMessage() {} func (*TrustedClusterV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{243} + return fileDescriptor_9198ee693835762e, []int{249} } func (m *TrustedClusterV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15185,7 +15462,7 @@ func (m *TrustedClusterV2List) Reset() { *m = TrustedClusterV2List{} } func (m *TrustedClusterV2List) String() string { return proto.CompactTextString(m) } func (*TrustedClusterV2List) ProtoMessage() {} func (*TrustedClusterV2List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{244} + return fileDescriptor_9198ee693835762e, []int{250} } func (m *TrustedClusterV2List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15241,7 +15518,7 @@ func (m *TrustedClusterSpecV2) Reset() { *m = TrustedClusterSpecV2{} } func (m *TrustedClusterSpecV2) String() string { return proto.CompactTextString(m) } func (*TrustedClusterSpecV2) ProtoMessage() {} func (*TrustedClusterSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{245} + return fileDescriptor_9198ee693835762e, []int{251} } func (m *TrustedClusterSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15295,7 +15572,7 @@ func (m *LockV2) Reset() { *m = LockV2{} } func (m *LockV2) String() string { return proto.CompactTextString(m) } func (*LockV2) ProtoMessage() {} func (*LockV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{246} + return fileDescriptor_9198ee693835762e, []int{252} } func (m *LockV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15345,7 +15622,7 @@ func (m *LockSpecV2) Reset() { *m = LockSpecV2{} } func (m *LockSpecV2) String() string { return proto.CompactTextString(m) } func (*LockSpecV2) ProtoMessage() {} func (*LockSpecV2) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{247} + return fileDescriptor_9198ee693835762e, []int{253} } func (m *LockSpecV2) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15409,7 +15686,7 @@ type LockTarget struct { func (m *LockTarget) Reset() { *m = LockTarget{} } func (*LockTarget) ProtoMessage() {} func (*LockTarget) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{248} + return fileDescriptor_9198ee693835762e, []int{254} } func (m *LockTarget) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15453,7 +15730,7 @@ func (m *AddressCondition) Reset() { *m = AddressCondition{} } func (m *AddressCondition) String() string { return proto.CompactTextString(m) } func (*AddressCondition) ProtoMessage() {} func (*AddressCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{249} + return fileDescriptor_9198ee693835762e, []int{255} } func (m *AddressCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15496,7 +15773,7 @@ func (m *NetworkRestrictionsSpecV4) Reset() { *m = NetworkRestrictionsSp func (m *NetworkRestrictionsSpecV4) String() string { return proto.CompactTextString(m) } func (*NetworkRestrictionsSpecV4) ProtoMessage() {} func (*NetworkRestrictionsSpecV4) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{250} + return fileDescriptor_9198ee693835762e, []int{256} } func (m *NetworkRestrictionsSpecV4) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15549,7 +15826,7 @@ func (m *NetworkRestrictionsV4) Reset() { *m = NetworkRestrictionsV4{} } func (m *NetworkRestrictionsV4) String() string { return proto.CompactTextString(m) } func (*NetworkRestrictionsV4) ProtoMessage() {} func (*NetworkRestrictionsV4) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{251} + return fileDescriptor_9198ee693835762e, []int{257} } func (m *NetworkRestrictionsV4) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15593,7 +15870,7 @@ func (m *WindowsDesktopServiceV3) Reset() { *m = WindowsDesktopServiceV3 func (m *WindowsDesktopServiceV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopServiceV3) ProtoMessage() {} func (*WindowsDesktopServiceV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{252} + return fileDescriptor_9198ee693835762e, []int{258} } func (m *WindowsDesktopServiceV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15641,7 +15918,7 @@ func (m *WindowsDesktopServiceSpecV3) Reset() { *m = WindowsDesktopServi func (m *WindowsDesktopServiceSpecV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopServiceSpecV3) ProtoMessage() {} func (*WindowsDesktopServiceSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{253} + return fileDescriptor_9198ee693835762e, []int{259} } func (m *WindowsDesktopServiceSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15685,7 +15962,7 @@ func (m *WindowsDesktopFilter) Reset() { *m = WindowsDesktopFilter{} } func (m *WindowsDesktopFilter) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopFilter) ProtoMessage() {} func (*WindowsDesktopFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{254} + return fileDescriptor_9198ee693835762e, []int{260} } func (m *WindowsDesktopFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15729,7 +16006,7 @@ func (m *WindowsDesktopV3) Reset() { *m = WindowsDesktopV3{} } func (m *WindowsDesktopV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopV3) ProtoMessage() {} func (*WindowsDesktopV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{255} + return fileDescriptor_9198ee693835762e, []int{261} } func (m *WindowsDesktopV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15782,7 +16059,7 @@ func (m *WindowsDesktopSpecV3) Reset() { *m = WindowsDesktopSpecV3{} } func (m *WindowsDesktopSpecV3) String() string { return proto.CompactTextString(m) } func (*WindowsDesktopSpecV3) ProtoMessage() {} func (*WindowsDesktopSpecV3) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{256} + return fileDescriptor_9198ee693835762e, []int{262} } func (m *WindowsDesktopSpecV3) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15826,7 +16103,7 @@ func (m *DynamicWindowsDesktopV1) Reset() { *m = DynamicWindowsDesktopV1 func (m *DynamicWindowsDesktopV1) String() string { return proto.CompactTextString(m) } func (*DynamicWindowsDesktopV1) ProtoMessage() {} func (*DynamicWindowsDesktopV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{257} + return fileDescriptor_9198ee693835762e, []int{263} } func (m *DynamicWindowsDesktopV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15877,7 +16154,7 @@ func (m *DynamicWindowsDesktopSpecV1) Reset() { *m = DynamicWindowsDeskt func (m *DynamicWindowsDesktopSpecV1) String() string { return proto.CompactTextString(m) } func (*DynamicWindowsDesktopSpecV1) ProtoMessage() {} func (*DynamicWindowsDesktopSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{258} + return fileDescriptor_9198ee693835762e, []int{264} } func (m *DynamicWindowsDesktopSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -15918,7 +16195,7 @@ func (m *Resolution) Reset() { *m = Resolution{} } func (m *Resolution) String() string { return proto.CompactTextString(m) } func (*Resolution) ProtoMessage() {} func (*Resolution) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{259} + return fileDescriptor_9198ee693835762e, []int{265} } func (m *Resolution) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16005,7 +16282,7 @@ func (m *RegisterUsingTokenRequest) Reset() { *m = RegisterUsingTokenReq func (m *RegisterUsingTokenRequest) String() string { return proto.CompactTextString(m) } func (*RegisterUsingTokenRequest) ProtoMessage() {} func (*RegisterUsingTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{260} + return fileDescriptor_9198ee693835762e, []int{266} } func (m *RegisterUsingTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16059,7 +16336,7 @@ func (m *RecoveryCodesV1) Reset() { *m = RecoveryCodesV1{} } func (m *RecoveryCodesV1) String() string { return proto.CompactTextString(m) } func (*RecoveryCodesV1) ProtoMessage() {} func (*RecoveryCodesV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{261} + return fileDescriptor_9198ee693835762e, []int{267} } func (m *RecoveryCodesV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16104,7 +16381,7 @@ func (m *RecoveryCodesSpecV1) Reset() { *m = RecoveryCodesSpecV1{} } func (m *RecoveryCodesSpecV1) String() string { return proto.CompactTextString(m) } func (*RecoveryCodesSpecV1) ProtoMessage() {} func (*RecoveryCodesSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{262} + return fileDescriptor_9198ee693835762e, []int{268} } func (m *RecoveryCodesSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16148,7 +16425,7 @@ func (m *RecoveryCode) Reset() { *m = RecoveryCode{} } func (m *RecoveryCode) String() string { return proto.CompactTextString(m) } func (*RecoveryCode) ProtoMessage() {} func (*RecoveryCode) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{263} + return fileDescriptor_9198ee693835762e, []int{269} } func (m *RecoveryCode) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16188,7 +16465,7 @@ func (m *NullableSessionState) Reset() { *m = NullableSessionState{} } func (m *NullableSessionState) String() string { return proto.CompactTextString(m) } func (*NullableSessionState) ProtoMessage() {} func (*NullableSessionState) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{264} + return fileDescriptor_9198ee693835762e, []int{270} } func (m *NullableSessionState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16234,7 +16511,7 @@ func (m *SessionTrackerFilter) Reset() { *m = SessionTrackerFilter{} } func (m *SessionTrackerFilter) String() string { return proto.CompactTextString(m) } func (*SessionTrackerFilter) ProtoMessage() {} func (*SessionTrackerFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{265} + return fileDescriptor_9198ee693835762e, []int{271} } func (m *SessionTrackerFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16278,7 +16555,7 @@ func (m *SessionTrackerV1) Reset() { *m = SessionTrackerV1{} } func (m *SessionTrackerV1) String() string { return proto.CompactTextString(m) } func (*SessionTrackerV1) ProtoMessage() {} func (*SessionTrackerV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{266} + return fileDescriptor_9198ee693835762e, []int{272} } func (m *SessionTrackerV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16376,7 +16653,7 @@ func (m *SessionTrackerSpecV1) Reset() { *m = SessionTrackerSpecV1{} } func (m *SessionTrackerSpecV1) String() string { return proto.CompactTextString(m) } func (*SessionTrackerSpecV1) ProtoMessage() {} func (*SessionTrackerSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{267} + return fileDescriptor_9198ee693835762e, []int{273} } func (m *SessionTrackerSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16423,7 +16700,7 @@ func (m *SessionTrackerPolicySet) Reset() { *m = SessionTrackerPolicySet func (m *SessionTrackerPolicySet) String() string { return proto.CompactTextString(m) } func (*SessionTrackerPolicySet) ProtoMessage() {} func (*SessionTrackerPolicySet) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{268} + return fileDescriptor_9198ee693835762e, []int{274} } func (m *SessionTrackerPolicySet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16471,7 +16748,7 @@ func (m *Participant) Reset() { *m = Participant{} } func (m *Participant) String() string { return proto.CompactTextString(m) } func (*Participant) ProtoMessage() {} func (*Participant) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{269} + return fileDescriptor_9198ee693835762e, []int{275} } func (m *Participant) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16515,7 +16792,7 @@ func (m *UIConfigV1) Reset() { *m = UIConfigV1{} } func (m *UIConfigV1) String() string { return proto.CompactTextString(m) } func (*UIConfigV1) ProtoMessage() {} func (*UIConfigV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{270} + return fileDescriptor_9198ee693835762e, []int{276} } func (m *UIConfigV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16561,7 +16838,7 @@ func (m *UIConfigSpecV1) Reset() { *m = UIConfigSpecV1{} } func (m *UIConfigSpecV1) String() string { return proto.CompactTextString(m) } func (*UIConfigSpecV1) ProtoMessage() {} func (*UIConfigSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{271} + return fileDescriptor_9198ee693835762e, []int{277} } func (m *UIConfigSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16612,7 +16889,7 @@ func (m *InstallerV1) Reset() { *m = InstallerV1{} } func (m *InstallerV1) String() string { return proto.CompactTextString(m) } func (*InstallerV1) ProtoMessage() {} func (*InstallerV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{272} + return fileDescriptor_9198ee693835762e, []int{278} } func (m *InstallerV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16654,7 +16931,7 @@ func (m *InstallerSpecV1) Reset() { *m = InstallerSpecV1{} } func (m *InstallerSpecV1) String() string { return proto.CompactTextString(m) } func (*InstallerSpecV1) ProtoMessage() {} func (*InstallerSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{273} + return fileDescriptor_9198ee693835762e, []int{279} } func (m *InstallerSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16696,7 +16973,7 @@ func (m *InstallerV1List) Reset() { *m = InstallerV1List{} } func (m *InstallerV1List) String() string { return proto.CompactTextString(m) } func (*InstallerV1List) ProtoMessage() {} func (*InstallerV1List) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{274} + return fileDescriptor_9198ee693835762e, []int{280} } func (m *InstallerV1List) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16740,7 +17017,7 @@ func (m *SortBy) Reset() { *m = SortBy{} } func (m *SortBy) String() string { return proto.CompactTextString(m) } func (*SortBy) ProtoMessage() {} func (*SortBy) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{275} + return fileDescriptor_9198ee693835762e, []int{281} } func (m *SortBy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16786,7 +17063,7 @@ func (m *ConnectionDiagnosticV1) Reset() { *m = ConnectionDiagnosticV1{} func (m *ConnectionDiagnosticV1) String() string { return proto.CompactTextString(m) } func (*ConnectionDiagnosticV1) ProtoMessage() {} func (*ConnectionDiagnosticV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{276} + return fileDescriptor_9198ee693835762e, []int{282} } func (m *ConnectionDiagnosticV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16836,7 +17113,7 @@ func (m *ConnectionDiagnosticSpecV1) Reset() { *m = ConnectionDiagnostic func (m *ConnectionDiagnosticSpecV1) String() string { return proto.CompactTextString(m) } func (*ConnectionDiagnosticSpecV1) ProtoMessage() {} func (*ConnectionDiagnosticSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{277} + return fileDescriptor_9198ee693835762e, []int{283} } func (m *ConnectionDiagnosticSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16882,7 +17159,7 @@ func (m *ConnectionDiagnosticTrace) Reset() { *m = ConnectionDiagnosticT func (m *ConnectionDiagnosticTrace) String() string { return proto.CompactTextString(m) } func (*ConnectionDiagnosticTrace) ProtoMessage() {} func (*ConnectionDiagnosticTrace) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{278} + return fileDescriptor_9198ee693835762e, []int{284} } func (m *ConnectionDiagnosticTrace) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16925,7 +17202,7 @@ func (m *DatabaseServiceV1) Reset() { *m = DatabaseServiceV1{} } func (m *DatabaseServiceV1) String() string { return proto.CompactTextString(m) } func (*DatabaseServiceV1) ProtoMessage() {} func (*DatabaseServiceV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{279} + return fileDescriptor_9198ee693835762e, []int{285} } func (m *DatabaseServiceV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -16969,7 +17246,7 @@ func (m *DatabaseServiceSpecV1) Reset() { *m = DatabaseServiceSpecV1{} } func (m *DatabaseServiceSpecV1) String() string { return proto.CompactTextString(m) } func (*DatabaseServiceSpecV1) ProtoMessage() {} func (*DatabaseServiceSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{280} + return fileDescriptor_9198ee693835762e, []int{286} } func (m *DatabaseServiceSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17011,7 +17288,7 @@ func (m *DatabaseResourceMatcher) Reset() { *m = DatabaseResourceMatcher func (m *DatabaseResourceMatcher) String() string { return proto.CompactTextString(m) } func (*DatabaseResourceMatcher) ProtoMessage() {} func (*DatabaseResourceMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{281} + return fileDescriptor_9198ee693835762e, []int{287} } func (m *DatabaseResourceMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17055,7 +17332,7 @@ func (m *ResourceMatcherAWS) Reset() { *m = ResourceMatcherAWS{} } func (m *ResourceMatcherAWS) String() string { return proto.CompactTextString(m) } func (*ResourceMatcherAWS) ProtoMessage() {} func (*ResourceMatcherAWS) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{282} + return fileDescriptor_9198ee693835762e, []int{288} } func (m *ResourceMatcherAWS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17097,7 +17374,7 @@ func (m *ClusterAlert) Reset() { *m = ClusterAlert{} } func (m *ClusterAlert) String() string { return proto.CompactTextString(m) } func (*ClusterAlert) ProtoMessage() {} func (*ClusterAlert) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{283} + return fileDescriptor_9198ee693835762e, []int{289} } func (m *ClusterAlert) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17143,7 +17420,7 @@ func (m *ClusterAlertSpec) Reset() { *m = ClusterAlertSpec{} } func (m *ClusterAlertSpec) String() string { return proto.CompactTextString(m) } func (*ClusterAlertSpec) ProtoMessage() {} func (*ClusterAlertSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{284} + return fileDescriptor_9198ee693835762e, []int{290} } func (m *ClusterAlertSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17196,7 +17473,7 @@ func (m *GetClusterAlertsRequest) Reset() { *m = GetClusterAlertsRequest func (m *GetClusterAlertsRequest) String() string { return proto.CompactTextString(m) } func (*GetClusterAlertsRequest) ProtoMessage() {} func (*GetClusterAlertsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{285} + return fileDescriptor_9198ee693835762e, []int{291} } func (m *GetClusterAlertsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17246,7 +17523,7 @@ func (m *AlertAcknowledgement) Reset() { *m = AlertAcknowledgement{} } func (m *AlertAcknowledgement) String() string { return proto.CompactTextString(m) } func (*AlertAcknowledgement) ProtoMessage() {} func (*AlertAcknowledgement) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{286} + return fileDescriptor_9198ee693835762e, []int{292} } func (m *AlertAcknowledgement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17298,7 +17575,7 @@ func (m *Release) Reset() { *m = Release{} } func (m *Release) String() string { return proto.CompactTextString(m) } func (*Release) ProtoMessage() {} func (*Release) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{287} + return fileDescriptor_9198ee693835762e, []int{293} } func (m *Release) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17356,7 +17633,7 @@ func (m *Asset) Reset() { *m = Asset{} } func (m *Asset) String() string { return proto.CompactTextString(m) } func (*Asset) ProtoMessage() {} func (*Asset) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{288} + return fileDescriptor_9198ee693835762e, []int{294} } func (m *Asset) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17409,7 +17686,7 @@ func (m *PluginV1) Reset() { *m = PluginV1{} } func (m *PluginV1) String() string { return proto.CompactTextString(m) } func (*PluginV1) ProtoMessage() {} func (*PluginV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{289} + return fileDescriptor_9198ee693835762e, []int{295} } func (m *PluginV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17479,7 +17756,7 @@ func (m *PluginSpecV1) Reset() { *m = PluginSpecV1{} } func (m *PluginSpecV1) String() string { return proto.CompactTextString(m) } func (*PluginSpecV1) ProtoMessage() {} func (*PluginSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{290} + return fileDescriptor_9198ee693835762e, []int{296} } func (m *PluginSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17795,7 +18072,7 @@ func (m *PluginGithubSettings) Reset() { *m = PluginGithubSettings{} } func (m *PluginGithubSettings) String() string { return proto.CompactTextString(m) } func (*PluginGithubSettings) ProtoMessage() {} func (*PluginGithubSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{291} + return fileDescriptor_9198ee693835762e, []int{297} } func (m *PluginGithubSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17835,7 +18112,7 @@ func (m *PluginSlackAccessSettings) Reset() { *m = PluginSlackAccessSett func (m *PluginSlackAccessSettings) String() string { return proto.CompactTextString(m) } func (*PluginSlackAccessSettings) ProtoMessage() {} func (*PluginSlackAccessSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{292} + return fileDescriptor_9198ee693835762e, []int{298} } func (m *PluginSlackAccessSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17876,7 +18153,7 @@ func (m *PluginGitlabSettings) Reset() { *m = PluginGitlabSettings{} } func (m *PluginGitlabSettings) String() string { return proto.CompactTextString(m) } func (*PluginGitlabSettings) ProtoMessage() {} func (*PluginGitlabSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{293} + return fileDescriptor_9198ee693835762e, []int{299} } func (m *PluginGitlabSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17923,7 +18200,7 @@ func (m *PluginOpsgenieAccessSettings) Reset() { *m = PluginOpsgenieAcce func (m *PluginOpsgenieAccessSettings) String() string { return proto.CompactTextString(m) } func (*PluginOpsgenieAccessSettings) ProtoMessage() {} func (*PluginOpsgenieAccessSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{294} + return fileDescriptor_9198ee693835762e, []int{300} } func (m *PluginOpsgenieAccessSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -17971,7 +18248,7 @@ func (m *PluginServiceNowSettings) Reset() { *m = PluginServiceNowSettin func (m *PluginServiceNowSettings) String() string { return proto.CompactTextString(m) } func (*PluginServiceNowSettings) ProtoMessage() {} func (*PluginServiceNowSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{295} + return fileDescriptor_9198ee693835762e, []int{301} } func (m *PluginServiceNowSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18017,7 +18294,7 @@ func (m *PluginPagerDutySettings) Reset() { *m = PluginPagerDutySettings func (m *PluginPagerDutySettings) String() string { return proto.CompactTextString(m) } func (*PluginPagerDutySettings) ProtoMessage() {} func (*PluginPagerDutySettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{296} + return fileDescriptor_9198ee693835762e, []int{302} } func (m *PluginPagerDutySettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18063,7 +18340,7 @@ func (m *PluginJiraSettings) Reset() { *m = PluginJiraSettings{} } func (m *PluginJiraSettings) String() string { return proto.CompactTextString(m) } func (*PluginJiraSettings) ProtoMessage() {} func (*PluginJiraSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{297} + return fileDescriptor_9198ee693835762e, []int{303} } func (m *PluginJiraSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18103,7 +18380,7 @@ func (m *PluginOpenAISettings) Reset() { *m = PluginOpenAISettings{} } func (m *PluginOpenAISettings) String() string { return proto.CompactTextString(m) } func (*PluginOpenAISettings) ProtoMessage() {} func (*PluginOpenAISettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{298} + return fileDescriptor_9198ee693835762e, []int{304} } func (m *PluginOpenAISettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18154,7 +18431,7 @@ func (m *PluginMattermostSettings) Reset() { *m = PluginMattermostSettin func (m *PluginMattermostSettings) String() string { return proto.CompactTextString(m) } func (*PluginMattermostSettings) ProtoMessage() {} func (*PluginMattermostSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{299} + return fileDescriptor_9198ee693835762e, []int{305} } func (m *PluginMattermostSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18196,7 +18473,7 @@ func (m *PluginJamfSettings) Reset() { *m = PluginJamfSettings{} } func (m *PluginJamfSettings) String() string { return proto.CompactTextString(m) } func (*PluginJamfSettings) ProtoMessage() {} func (*PluginJamfSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{300} + return fileDescriptor_9198ee693835762e, []int{306} } func (m *PluginJamfSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18251,7 +18528,7 @@ func (m *PluginIntuneSettings) Reset() { *m = PluginIntuneSettings{} } func (m *PluginIntuneSettings) String() string { return proto.CompactTextString(m) } func (*PluginIntuneSettings) ProtoMessage() {} func (*PluginIntuneSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{301} + return fileDescriptor_9198ee693835762e, []int{307} } func (m *PluginIntuneSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18303,7 +18580,7 @@ func (m *PluginOktaSettings) Reset() { *m = PluginOktaSettings{} } func (m *PluginOktaSettings) String() string { return proto.CompactTextString(m) } func (*PluginOktaSettings) ProtoMessage() {} func (*PluginOktaSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{302} + return fileDescriptor_9198ee693835762e, []int{308} } func (m *PluginOktaSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18350,7 +18627,7 @@ func (m *PluginOktaCredentialsInfo) Reset() { *m = PluginOktaCredentials func (m *PluginOktaCredentialsInfo) String() string { return proto.CompactTextString(m) } func (*PluginOktaCredentialsInfo) ProtoMessage() {} func (*PluginOktaCredentialsInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{303} + return fileDescriptor_9198ee693835762e, []int{309} } func (m *PluginOktaCredentialsInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18451,7 +18728,7 @@ func (m *PluginOktaSyncSettings) Reset() { *m = PluginOktaSyncSettings{} func (m *PluginOktaSyncSettings) String() string { return proto.CompactTextString(m) } func (*PluginOktaSyncSettings) ProtoMessage() {} func (*PluginOktaSyncSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{304} + return fileDescriptor_9198ee693835762e, []int{310} } func (m *PluginOktaSyncSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18492,7 +18769,7 @@ func (m *DiscordChannels) Reset() { *m = DiscordChannels{} } func (m *DiscordChannels) String() string { return proto.CompactTextString(m) } func (*DiscordChannels) ProtoMessage() {} func (*DiscordChannels) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{305} + return fileDescriptor_9198ee693835762e, []int{311} } func (m *DiscordChannels) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18536,7 +18813,7 @@ func (m *PluginDiscordSettings) Reset() { *m = PluginDiscordSettings{} } func (m *PluginDiscordSettings) String() string { return proto.CompactTextString(m) } func (*PluginDiscordSettings) ProtoMessage() {} func (*PluginDiscordSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{306} + return fileDescriptor_9198ee693835762e, []int{312} } func (m *PluginDiscordSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18581,7 +18858,7 @@ func (m *PluginEntraIDSettings) Reset() { *m = PluginEntraIDSettings{} } func (m *PluginEntraIDSettings) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDSettings) ProtoMessage() {} func (*PluginEntraIDSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{307} + return fileDescriptor_9198ee693835762e, []int{313} } func (m *PluginEntraIDSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18635,7 +18912,7 @@ func (m *PluginEntraIDSyncSettings) Reset() { *m = PluginEntraIDSyncSett func (m *PluginEntraIDSyncSettings) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDSyncSettings) ProtoMessage() {} func (*PluginEntraIDSyncSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{308} + return fileDescriptor_9198ee693835762e, []int{314} } func (m *PluginEntraIDSyncSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18680,7 +18957,7 @@ func (m *PluginEntraIDAccessGraphSettings) Reset() { *m = PluginEntraIDA func (m *PluginEntraIDAccessGraphSettings) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDAccessGraphSettings) ProtoMessage() {} func (*PluginEntraIDAccessGraphSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{309} + return fileDescriptor_9198ee693835762e, []int{315} } func (m *PluginEntraIDAccessGraphSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18726,7 +19003,7 @@ func (m *PluginEntraIDAppSSOSettings) Reset() { *m = PluginEntraIDAppSSO func (m *PluginEntraIDAppSSOSettings) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDAppSSOSettings) ProtoMessage() {} func (*PluginEntraIDAppSSOSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{310} + return fileDescriptor_9198ee693835762e, []int{316} } func (m *PluginEntraIDAppSSOSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18772,7 +19049,7 @@ func (m *PluginSCIMSettings) Reset() { *m = PluginSCIMSettings{} } func (m *PluginSCIMSettings) String() string { return proto.CompactTextString(m) } func (*PluginSCIMSettings) ProtoMessage() {} func (*PluginSCIMSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{311} + return fileDescriptor_9198ee693835762e, []int{317} } func (m *PluginSCIMSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18816,7 +19093,7 @@ func (m *PluginDatadogAccessSettings) Reset() { *m = PluginDatadogAccess func (m *PluginDatadogAccessSettings) String() string { return proto.CompactTextString(m) } func (*PluginDatadogAccessSettings) ProtoMessage() {} func (*PluginDatadogAccessSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{312} + return fileDescriptor_9198ee693835762e, []int{318} } func (m *PluginDatadogAccessSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18918,7 +19195,7 @@ func (m *PluginAWSICSettings) Reset() { *m = PluginAWSICSettings{} } func (m *PluginAWSICSettings) String() string { return proto.CompactTextString(m) } func (*PluginAWSICSettings) ProtoMessage() {} func (*PluginAWSICSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{313} + return fileDescriptor_9198ee693835762e, []int{319} } func (m *PluginAWSICSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -18963,7 +19240,7 @@ func (m *AWSICCredentials) Reset() { *m = AWSICCredentials{} } func (m *AWSICCredentials) String() string { return proto.CompactTextString(m) } func (*AWSICCredentials) ProtoMessage() {} func (*AWSICCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{314} + return fileDescriptor_9198ee693835762e, []int{320} } func (m *AWSICCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19053,7 +19330,7 @@ func (m *AWSICCredentialSourceSystem) Reset() { *m = AWSICCredentialSour func (m *AWSICCredentialSourceSystem) String() string { return proto.CompactTextString(m) } func (*AWSICCredentialSourceSystem) ProtoMessage() {} func (*AWSICCredentialSourceSystem) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{315} + return fileDescriptor_9198ee693835762e, []int{321} } func (m *AWSICCredentialSourceSystem) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19097,7 +19374,7 @@ func (m *AWSICCredentialSourceOIDC) Reset() { *m = AWSICCredentialSource func (m *AWSICCredentialSourceOIDC) String() string { return proto.CompactTextString(m) } func (*AWSICCredentialSourceOIDC) ProtoMessage() {} func (*AWSICCredentialSourceOIDC) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{316} + return fileDescriptor_9198ee693835762e, []int{322} } func (m *AWSICCredentialSourceOIDC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19153,7 +19430,7 @@ func (m *AWSICResourceFilter) Reset() { *m = AWSICResourceFilter{} } func (m *AWSICResourceFilter) String() string { return proto.CompactTextString(m) } func (*AWSICResourceFilter) ProtoMessage() {} func (*AWSICResourceFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{317} + return fileDescriptor_9198ee693835762e, []int{323} } func (m *AWSICResourceFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19276,7 +19553,7 @@ func (m *AWSICUserSyncFilter) Reset() { *m = AWSICUserSyncFilter{} } func (m *AWSICUserSyncFilter) String() string { return proto.CompactTextString(m) } func (*AWSICUserSyncFilter) ProtoMessage() {} func (*AWSICUserSyncFilter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{318} + return fileDescriptor_9198ee693835762e, []int{324} } func (m *AWSICUserSyncFilter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19323,7 +19600,7 @@ func (m *AWSICProvisioningSpec) Reset() { *m = AWSICProvisioningSpec{} } func (m *AWSICProvisioningSpec) String() string { return proto.CompactTextString(m) } func (*AWSICProvisioningSpec) ProtoMessage() {} func (*AWSICProvisioningSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{319} + return fileDescriptor_9198ee693835762e, []int{325} } func (m *AWSICProvisioningSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19365,7 +19642,7 @@ func (m *PluginAWSICStatusV1) Reset() { *m = PluginAWSICStatusV1{} } func (m *PluginAWSICStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginAWSICStatusV1) ProtoMessage() {} func (*PluginAWSICStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{320} + return fileDescriptor_9198ee693835762e, []int{326} } func (m *PluginAWSICStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19410,7 +19687,7 @@ func (m *AWSICGroupImportStatus) Reset() { *m = AWSICGroupImportStatus{} func (m *AWSICGroupImportStatus) String() string { return proto.CompactTextString(m) } func (*AWSICGroupImportStatus) ProtoMessage() {} func (*AWSICGroupImportStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{321} + return fileDescriptor_9198ee693835762e, []int{327} } func (m *AWSICGroupImportStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19461,7 +19738,7 @@ func (m *PluginEmailSettings) Reset() { *m = PluginEmailSettings{} } func (m *PluginEmailSettings) String() string { return proto.CompactTextString(m) } func (*PluginEmailSettings) ProtoMessage() {} func (*PluginEmailSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{322} + return fileDescriptor_9198ee693835762e, []int{328} } func (m *PluginEmailSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19549,7 +19826,7 @@ func (m *MailgunSpec) Reset() { *m = MailgunSpec{} } func (m *MailgunSpec) String() string { return proto.CompactTextString(m) } func (*MailgunSpec) ProtoMessage() {} func (*MailgunSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{323} + return fileDescriptor_9198ee693835762e, []int{329} } func (m *MailgunSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19596,7 +19873,7 @@ func (m *SMTPSpec) Reset() { *m = SMTPSpec{} } func (m *SMTPSpec) String() string { return proto.CompactTextString(m) } func (*SMTPSpec) ProtoMessage() {} func (*SMTPSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{324} + return fileDescriptor_9198ee693835762e, []int{330} } func (m *SMTPSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19646,7 +19923,7 @@ func (m *PluginMSTeamsSettings) Reset() { *m = PluginMSTeamsSettings{} } func (m *PluginMSTeamsSettings) String() string { return proto.CompactTextString(m) } func (*PluginMSTeamsSettings) ProtoMessage() {} func (*PluginMSTeamsSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{325} + return fileDescriptor_9198ee693835762e, []int{331} } func (m *PluginMSTeamsSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19693,7 +19970,7 @@ func (m *PluginNetIQSettings) Reset() { *m = PluginNetIQSettings{} } func (m *PluginNetIQSettings) String() string { return proto.CompactTextString(m) } func (*PluginNetIQSettings) ProtoMessage() {} func (*PluginNetIQSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{326} + return fileDescriptor_9198ee693835762e, []int{332} } func (m *PluginNetIQSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19738,7 +20015,7 @@ func (m *PluginBootstrapCredentialsV1) Reset() { *m = PluginBootstrapCre func (m *PluginBootstrapCredentialsV1) String() string { return proto.CompactTextString(m) } func (*PluginBootstrapCredentialsV1) ProtoMessage() {} func (*PluginBootstrapCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{327} + return fileDescriptor_9198ee693835762e, []int{333} } func (m *PluginBootstrapCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19838,7 +20115,7 @@ func (m *PluginIdSecretCredential) Reset() { *m = PluginIdSecretCredenti func (m *PluginIdSecretCredential) String() string { return proto.CompactTextString(m) } func (*PluginIdSecretCredential) ProtoMessage() {} func (*PluginIdSecretCredential) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{328} + return fileDescriptor_9198ee693835762e, []int{334} } func (m *PluginIdSecretCredential) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19881,7 +20158,7 @@ func (m *PluginOAuth2AuthorizationCodeCredentials) Reset() { func (m *PluginOAuth2AuthorizationCodeCredentials) String() string { return proto.CompactTextString(m) } func (*PluginOAuth2AuthorizationCodeCredentials) ProtoMessage() {} func (*PluginOAuth2AuthorizationCodeCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{329} + return fileDescriptor_9198ee693835762e, []int{335} } func (m *PluginOAuth2AuthorizationCodeCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -19941,7 +20218,7 @@ func (m *PluginStatusV1) Reset() { *m = PluginStatusV1{} } func (m *PluginStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginStatusV1) ProtoMessage() {} func (*PluginStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{330} + return fileDescriptor_9198ee693835762e, []int{336} } func (m *PluginStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20070,7 +20347,7 @@ func (m *PluginNetIQStatusV1) Reset() { *m = PluginNetIQStatusV1{} } func (m *PluginNetIQStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginNetIQStatusV1) ProtoMessage() {} func (*PluginNetIQStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{331} + return fileDescriptor_9198ee693835762e, []int{337} } func (m *PluginNetIQStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20116,7 +20393,7 @@ func (m *PluginGitlabStatusV1) Reset() { *m = PluginGitlabStatusV1{} } func (m *PluginGitlabStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginGitlabStatusV1) ProtoMessage() {} func (*PluginGitlabStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{332} + return fileDescriptor_9198ee693835762e, []int{338} } func (m *PluginGitlabStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20160,7 +20437,7 @@ func (m *PluginEntraIDStatusV1) Reset() { *m = PluginEntraIDStatusV1{} } func (m *PluginEntraIDStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginEntraIDStatusV1) ProtoMessage() {} func (*PluginEntraIDStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{333} + return fileDescriptor_9198ee693835762e, []int{339} } func (m *PluginEntraIDStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20217,7 +20494,7 @@ func (m *PluginOktaStatusV1) Reset() { *m = PluginOktaStatusV1{} } func (m *PluginOktaStatusV1) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusV1) ProtoMessage() {} func (*PluginOktaStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{334} + return fileDescriptor_9198ee693835762e, []int{340} } func (m *PluginOktaStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20270,7 +20547,7 @@ func (m *PluginOktaStatusDetailsSSO) Reset() { *m = PluginOktaStatusDeta func (m *PluginOktaStatusDetailsSSO) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsSSO) ProtoMessage() {} func (*PluginOktaStatusDetailsSSO) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{335} + return fileDescriptor_9198ee693835762e, []int{341} } func (m *PluginOktaStatusDetailsSSO) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20327,7 +20604,7 @@ func (m *PluginOktaStatusDetailsAppGroupSync) Reset() { *m = PluginOktaS func (m *PluginOktaStatusDetailsAppGroupSync) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsAppGroupSync) ProtoMessage() {} func (*PluginOktaStatusDetailsAppGroupSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{336} + return fileDescriptor_9198ee693835762e, []int{342} } func (m *PluginOktaStatusDetailsAppGroupSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20381,7 +20658,7 @@ func (m *PluginOktaStatusDetailsUsersSync) Reset() { *m = PluginOktaStat func (m *PluginOktaStatusDetailsUsersSync) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsUsersSync) ProtoMessage() {} func (*PluginOktaStatusDetailsUsersSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{337} + return fileDescriptor_9198ee693835762e, []int{343} } func (m *PluginOktaStatusDetailsUsersSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20424,7 +20701,7 @@ func (m *PluginOktaStatusDetailsSCIM) Reset() { *m = PluginOktaStatusDet func (m *PluginOktaStatusDetailsSCIM) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsSCIM) ProtoMessage() {} func (*PluginOktaStatusDetailsSCIM) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{338} + return fileDescriptor_9198ee693835762e, []int{344} } func (m *PluginOktaStatusDetailsSCIM) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20486,7 +20763,7 @@ func (m *PluginOktaStatusDetailsAccessListsSync) Reset() { func (m *PluginOktaStatusDetailsAccessListsSync) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusDetailsAccessListsSync) ProtoMessage() {} func (*PluginOktaStatusDetailsAccessListsSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{339} + return fileDescriptor_9198ee693835762e, []int{345} } func (m *PluginOktaStatusDetailsAccessListsSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20538,7 +20815,7 @@ func (m *PluginOktaStatusSystemLogExporter) Reset() { *m = PluginOktaSta func (m *PluginOktaStatusSystemLogExporter) String() string { return proto.CompactTextString(m) } func (*PluginOktaStatusSystemLogExporter) ProtoMessage() {} func (*PluginOktaStatusSystemLogExporter) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{340} + return fileDescriptor_9198ee693835762e, []int{346} } func (m *PluginOktaStatusSystemLogExporter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20586,7 +20863,7 @@ func (m *PluginCredentialsV1) Reset() { *m = PluginCredentialsV1{} } func (m *PluginCredentialsV1) String() string { return proto.CompactTextString(m) } func (*PluginCredentialsV1) ProtoMessage() {} func (*PluginCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{341} + return fileDescriptor_9198ee693835762e, []int{347} } func (m *PluginCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20698,7 +20975,7 @@ func (m *PluginOAuth2AccessTokenCredentials) Reset() { *m = PluginOAuth2 func (m *PluginOAuth2AccessTokenCredentials) String() string { return proto.CompactTextString(m) } func (*PluginOAuth2AccessTokenCredentials) ProtoMessage() {} func (*PluginOAuth2AccessTokenCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{342} + return fileDescriptor_9198ee693835762e, []int{348} } func (m *PluginOAuth2AccessTokenCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20739,7 +21016,7 @@ func (m *PluginBearerTokenCredentials) Reset() { *m = PluginBearerTokenC func (m *PluginBearerTokenCredentials) String() string { return proto.CompactTextString(m) } func (*PluginBearerTokenCredentials) ProtoMessage() {} func (*PluginBearerTokenCredentials) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{343} + return fileDescriptor_9198ee693835762e, []int{349} } func (m *PluginBearerTokenCredentials) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20781,7 +21058,7 @@ func (m *PluginStaticCredentialsRef) Reset() { *m = PluginStaticCredenti func (m *PluginStaticCredentialsRef) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsRef) ProtoMessage() {} func (*PluginStaticCredentialsRef) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{344} + return fileDescriptor_9198ee693835762e, []int{350} } func (m *PluginStaticCredentialsRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20823,7 +21100,7 @@ func (m *PluginListV1) Reset() { *m = PluginListV1{} } func (m *PluginListV1) String() string { return proto.CompactTextString(m) } func (*PluginListV1) ProtoMessage() {} func (*PluginListV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{345} + return fileDescriptor_9198ee693835762e, []int{351} } func (m *PluginListV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20866,7 +21143,7 @@ type PluginStaticCredentialsV1 struct { func (m *PluginStaticCredentialsV1) Reset() { *m = PluginStaticCredentialsV1{} } func (*PluginStaticCredentialsV1) ProtoMessage() {} func (*PluginStaticCredentialsV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{346} + return fileDescriptor_9198ee693835762e, []int{352} } func (m *PluginStaticCredentialsV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -20914,7 +21191,7 @@ func (m *PluginStaticCredentialsSpecV1) Reset() { *m = PluginStaticCrede func (m *PluginStaticCredentialsSpecV1) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsSpecV1) ProtoMessage() {} func (*PluginStaticCredentialsSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{347} + return fileDescriptor_9198ee693835762e, []int{353} } func (m *PluginStaticCredentialsSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21042,7 +21319,7 @@ func (m *PluginStaticCredentialsBasicAuth) Reset() { *m = PluginStaticCr func (m *PluginStaticCredentialsBasicAuth) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsBasicAuth) ProtoMessage() {} func (*PluginStaticCredentialsBasicAuth) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{348} + return fileDescriptor_9198ee693835762e, []int{354} } func (m *PluginStaticCredentialsBasicAuth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21088,7 +21365,7 @@ func (m *PluginStaticCredentialsOAuthClientSecret) Reset() { func (m *PluginStaticCredentialsOAuthClientSecret) String() string { return proto.CompactTextString(m) } func (*PluginStaticCredentialsOAuthClientSecret) ProtoMessage() {} func (*PluginStaticCredentialsOAuthClientSecret) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{349} + return fileDescriptor_9198ee693835762e, []int{355} } func (m *PluginStaticCredentialsOAuthClientSecret) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21136,7 +21413,7 @@ func (m *PluginStaticCredentialsSSHCertAuthorities) String() string { } func (*PluginStaticCredentialsSSHCertAuthorities) ProtoMessage() {} func (*PluginStaticCredentialsSSHCertAuthorities) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{350} + return fileDescriptor_9198ee693835762e, []int{356} } func (m *PluginStaticCredentialsSSHCertAuthorities) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21179,7 +21456,7 @@ type SAMLIdPServiceProviderV1 struct { func (m *SAMLIdPServiceProviderV1) Reset() { *m = SAMLIdPServiceProviderV1{} } func (*SAMLIdPServiceProviderV1) ProtoMessage() {} func (*SAMLIdPServiceProviderV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{351} + return fileDescriptor_9198ee693835762e, []int{357} } func (m *SAMLIdPServiceProviderV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21250,7 +21527,7 @@ func (m *SAMLIdPServiceProviderSpecV1) Reset() { *m = SAMLIdPServiceProv func (m *SAMLIdPServiceProviderSpecV1) String() string { return proto.CompactTextString(m) } func (*SAMLIdPServiceProviderSpecV1) ProtoMessage() {} func (*SAMLIdPServiceProviderSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{352} + return fileDescriptor_9198ee693835762e, []int{358} } func (m *SAMLIdPServiceProviderSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21297,7 +21574,7 @@ func (m *SAMLAttributeMapping) Reset() { *m = SAMLAttributeMapping{} } func (m *SAMLAttributeMapping) String() string { return proto.CompactTextString(m) } func (*SAMLAttributeMapping) ProtoMessage() {} func (*SAMLAttributeMapping) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{353} + return fileDescriptor_9198ee693835762e, []int{359} } func (m *SAMLAttributeMapping) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21339,7 +21616,7 @@ func (m *IdPOptions) Reset() { *m = IdPOptions{} } func (m *IdPOptions) String() string { return proto.CompactTextString(m) } func (*IdPOptions) ProtoMessage() {} func (*IdPOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{354} + return fileDescriptor_9198ee693835762e, []int{360} } func (m *IdPOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21381,7 +21658,7 @@ func (m *IdPSAMLOptions) Reset() { *m = IdPSAMLOptions{} } func (m *IdPSAMLOptions) String() string { return proto.CompactTextString(m) } func (*IdPSAMLOptions) ProtoMessage() {} func (*IdPSAMLOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{355} + return fileDescriptor_9198ee693835762e, []int{361} } func (m *IdPSAMLOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21431,7 +21708,7 @@ func (m *KubernetesResourceV1) Reset() { *m = KubernetesResourceV1{} } func (m *KubernetesResourceV1) String() string { return proto.CompactTextString(m) } func (*KubernetesResourceV1) ProtoMessage() {} func (*KubernetesResourceV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{356} + return fileDescriptor_9198ee693835762e, []int{362} } func (m *KubernetesResourceV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21473,7 +21750,7 @@ func (m *KubernetesResourceSpecV1) Reset() { *m = KubernetesResourceSpec func (m *KubernetesResourceSpecV1) String() string { return proto.CompactTextString(m) } func (*KubernetesResourceSpecV1) ProtoMessage() {} func (*KubernetesResourceSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{357} + return fileDescriptor_9198ee693835762e, []int{363} } func (m *KubernetesResourceSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21519,7 +21796,7 @@ func (m *ClusterMaintenanceConfigV1) Reset() { *m = ClusterMaintenanceCo func (m *ClusterMaintenanceConfigV1) String() string { return proto.CompactTextString(m) } func (*ClusterMaintenanceConfigV1) ProtoMessage() {} func (*ClusterMaintenanceConfigV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{358} + return fileDescriptor_9198ee693835762e, []int{364} } func (m *ClusterMaintenanceConfigV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21561,7 +21838,7 @@ func (m *ClusterMaintenanceConfigSpecV1) Reset() { *m = ClusterMaintenan func (m *ClusterMaintenanceConfigSpecV1) String() string { return proto.CompactTextString(m) } func (*ClusterMaintenanceConfigSpecV1) ProtoMessage() {} func (*ClusterMaintenanceConfigSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{359} + return fileDescriptor_9198ee693835762e, []int{365} } func (m *ClusterMaintenanceConfigSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21607,7 +21884,7 @@ func (m *AgentUpgradeWindow) Reset() { *m = AgentUpgradeWindow{} } func (m *AgentUpgradeWindow) String() string { return proto.CompactTextString(m) } func (*AgentUpgradeWindow) ProtoMessage() {} func (*AgentUpgradeWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{360} + return fileDescriptor_9198ee693835762e, []int{366} } func (m *AgentUpgradeWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21654,7 +21931,7 @@ func (m *ScheduledAgentUpgradeWindow) Reset() { *m = ScheduledAgentUpgra func (m *ScheduledAgentUpgradeWindow) String() string { return proto.CompactTextString(m) } func (*ScheduledAgentUpgradeWindow) ProtoMessage() {} func (*ScheduledAgentUpgradeWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{361} + return fileDescriptor_9198ee693835762e, []int{367} } func (m *ScheduledAgentUpgradeWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21697,7 +21974,7 @@ func (m *AgentUpgradeSchedule) Reset() { *m = AgentUpgradeSchedule{} } func (m *AgentUpgradeSchedule) String() string { return proto.CompactTextString(m) } func (*AgentUpgradeSchedule) ProtoMessage() {} func (*AgentUpgradeSchedule) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{362} + return fileDescriptor_9198ee693835762e, []int{368} } func (m *AgentUpgradeSchedule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21740,7 +22017,7 @@ type UserGroupV1 struct { func (m *UserGroupV1) Reset() { *m = UserGroupV1{} } func (*UserGroupV1) ProtoMessage() {} func (*UserGroupV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{363} + return fileDescriptor_9198ee693835762e, []int{369} } func (m *UserGroupV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21782,7 +22059,7 @@ func (m *UserGroupSpecV1) Reset() { *m = UserGroupSpecV1{} } func (m *UserGroupSpecV1) String() string { return proto.CompactTextString(m) } func (*UserGroupSpecV1) ProtoMessage() {} func (*UserGroupSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{364} + return fileDescriptor_9198ee693835762e, []int{370} } func (m *UserGroupSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21826,7 +22103,7 @@ func (m *OktaImportRuleSpecV1) Reset() { *m = OktaImportRuleSpecV1{} } func (m *OktaImportRuleSpecV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleSpecV1) ProtoMessage() {} func (*OktaImportRuleSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{365} + return fileDescriptor_9198ee693835762e, []int{371} } func (m *OktaImportRuleSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21870,7 +22147,7 @@ func (m *OktaImportRuleMappingV1) Reset() { *m = OktaImportRuleMappingV1 func (m *OktaImportRuleMappingV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleMappingV1) ProtoMessage() {} func (*OktaImportRuleMappingV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{366} + return fileDescriptor_9198ee693835762e, []int{372} } func (m *OktaImportRuleMappingV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21913,7 +22190,7 @@ type OktaImportRuleV1 struct { func (m *OktaImportRuleV1) Reset() { *m = OktaImportRuleV1{} } func (*OktaImportRuleV1) ProtoMessage() {} func (*OktaImportRuleV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{367} + return fileDescriptor_9198ee693835762e, []int{373} } func (m *OktaImportRuleV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -21961,7 +22238,7 @@ func (m *OktaImportRuleMatchV1) Reset() { *m = OktaImportRuleMatchV1{} } func (m *OktaImportRuleMatchV1) String() string { return proto.CompactTextString(m) } func (*OktaImportRuleMatchV1) ProtoMessage() {} func (*OktaImportRuleMatchV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{368} + return fileDescriptor_9198ee693835762e, []int{374} } func (m *OktaImportRuleMatchV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22004,7 +22281,7 @@ type OktaAssignmentV1 struct { func (m *OktaAssignmentV1) Reset() { *m = OktaAssignmentV1{} } func (*OktaAssignmentV1) ProtoMessage() {} func (*OktaAssignmentV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{369} + return fileDescriptor_9198ee693835762e, []int{375} } func (m *OktaAssignmentV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22058,7 +22335,7 @@ func (m *OktaAssignmentSpecV1) Reset() { *m = OktaAssignmentSpecV1{} } func (m *OktaAssignmentSpecV1) String() string { return proto.CompactTextString(m) } func (*OktaAssignmentSpecV1) ProtoMessage() {} func (*OktaAssignmentSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{370} + return fileDescriptor_9198ee693835762e, []int{376} } func (m *OktaAssignmentSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22102,7 +22379,7 @@ func (m *OktaAssignmentTargetV1) Reset() { *m = OktaAssignmentTargetV1{} func (m *OktaAssignmentTargetV1) String() string { return proto.CompactTextString(m) } func (*OktaAssignmentTargetV1) ProtoMessage() {} func (*OktaAssignmentTargetV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{371} + return fileDescriptor_9198ee693835762e, []int{377} } func (m *OktaAssignmentTargetV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22149,7 +22426,7 @@ type IntegrationV1 struct { func (m *IntegrationV1) Reset() { *m = IntegrationV1{} } func (*IntegrationV1) ProtoMessage() {} func (*IntegrationV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{372} + return fileDescriptor_9198ee693835762e, []int{378} } func (m *IntegrationV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22198,7 +22475,7 @@ func (m *IntegrationSpecV1) Reset() { *m = IntegrationSpecV1{} } func (m *IntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*IntegrationSpecV1) ProtoMessage() {} func (*IntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{373} + return fileDescriptor_9198ee693835762e, []int{379} } func (m *IntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22309,7 +22586,7 @@ func (m *IntegrationStatusV1) Reset() { *m = IntegrationStatusV1{} } func (m *IntegrationStatusV1) String() string { return proto.CompactTextString(m) } func (*IntegrationStatusV1) ProtoMessage() {} func (*IntegrationStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{374} + return fileDescriptor_9198ee693835762e, []int{380} } func (m *IntegrationStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22371,7 +22648,7 @@ func (m *AWSOIDCIntegrationSpecV1) Reset() { *m = AWSOIDCIntegrationSpec func (m *AWSOIDCIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*AWSOIDCIntegrationSpecV1) ProtoMessage() {} func (*AWSOIDCIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{375} + return fileDescriptor_9198ee693835762e, []int{381} } func (m *AWSOIDCIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22417,7 +22694,7 @@ func (m *AzureOIDCIntegrationSpecV1) Reset() { *m = AzureOIDCIntegration func (m *AzureOIDCIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*AzureOIDCIntegrationSpecV1) ProtoMessage() {} func (*AzureOIDCIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{376} + return fileDescriptor_9198ee693835762e, []int{382} } func (m *AzureOIDCIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22459,7 +22736,7 @@ func (m *GitHubIntegrationSpecV1) Reset() { *m = GitHubIntegrationSpecV1 func (m *GitHubIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*GitHubIntegrationSpecV1) ProtoMessage() {} func (*GitHubIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{377} + return fileDescriptor_9198ee693835762e, []int{383} } func (m *GitHubIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22504,7 +22781,7 @@ func (m *AWSRAIntegrationSpecV1) Reset() { *m = AWSRAIntegrationSpecV1{} func (m *AWSRAIntegrationSpecV1) String() string { return proto.CompactTextString(m) } func (*AWSRAIntegrationSpecV1) ProtoMessage() {} func (*AWSRAIntegrationSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{378} + return fileDescriptor_9198ee693835762e, []int{384} } func (m *AWSRAIntegrationSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22567,7 +22844,7 @@ func (m *AWSRolesAnywhereProfileSyncConfig) Reset() { *m = AWSRolesAnywh func (m *AWSRolesAnywhereProfileSyncConfig) String() string { return proto.CompactTextString(m) } func (*AWSRolesAnywhereProfileSyncConfig) ProtoMessage() {} func (*AWSRolesAnywhereProfileSyncConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{379} + return fileDescriptor_9198ee693835762e, []int{385} } func (m *AWSRolesAnywhereProfileSyncConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22609,7 +22886,7 @@ func (m *AWSRAIntegrationStatusV1) Reset() { *m = AWSRAIntegrationStatus func (m *AWSRAIntegrationStatusV1) String() string { return proto.CompactTextString(m) } func (*AWSRAIntegrationStatusV1) ProtoMessage() {} func (*AWSRAIntegrationStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{380} + return fileDescriptor_9198ee693835762e, []int{386} } func (m *AWSRAIntegrationStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22663,7 +22940,7 @@ func (m *AWSRolesAnywhereProfileSyncIterationSummary) String() string { } func (*AWSRolesAnywhereProfileSyncIterationSummary) ProtoMessage() {} func (*AWSRolesAnywhereProfileSyncIterationSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{381} + return fileDescriptor_9198ee693835762e, []int{387} } func (m *AWSRolesAnywhereProfileSyncIterationSummary) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22720,7 +22997,7 @@ func (m *HeadlessAuthentication) Reset() { *m = HeadlessAuthentication{} func (m *HeadlessAuthentication) String() string { return proto.CompactTextString(m) } func (*HeadlessAuthentication) ProtoMessage() {} func (*HeadlessAuthentication) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{382} + return fileDescriptor_9198ee693835762e, []int{388} } func (m *HeadlessAuthentication) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22777,7 +23054,7 @@ func (m *WatchKind) Reset() { *m = WatchKind{} } func (m *WatchKind) String() string { return proto.CompactTextString(m) } func (*WatchKind) ProtoMessage() {} func (*WatchKind) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{383} + return fileDescriptor_9198ee693835762e, []int{389} } func (m *WatchKind) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22827,7 +23104,7 @@ func (m *WatchStatusV1) Reset() { *m = WatchStatusV1{} } func (m *WatchStatusV1) String() string { return proto.CompactTextString(m) } func (*WatchStatusV1) ProtoMessage() {} func (*WatchStatusV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{384} + return fileDescriptor_9198ee693835762e, []int{390} } func (m *WatchStatusV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22868,7 +23145,7 @@ func (m *WatchStatusSpecV1) Reset() { *m = WatchStatusSpecV1{} } func (m *WatchStatusSpecV1) String() string { return proto.CompactTextString(m) } func (*WatchStatusSpecV1) ProtoMessage() {} func (*WatchStatusSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{385} + return fileDescriptor_9198ee693835762e, []int{391} } func (m *WatchStatusSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22918,7 +23195,7 @@ func (m *ServerInfoV1) Reset() { *m = ServerInfoV1{} } func (m *ServerInfoV1) String() string { return proto.CompactTextString(m) } func (*ServerInfoV1) ProtoMessage() {} func (*ServerInfoV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{386} + return fileDescriptor_9198ee693835762e, []int{392} } func (m *ServerInfoV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22960,7 +23237,7 @@ func (m *ServerInfoSpecV1) Reset() { *m = ServerInfoSpecV1{} } func (m *ServerInfoSpecV1) String() string { return proto.CompactTextString(m) } func (*ServerInfoSpecV1) ProtoMessage() {} func (*ServerInfoSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{387} + return fileDescriptor_9198ee693835762e, []int{393} } func (m *ServerInfoSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23017,7 +23294,7 @@ func (m *JamfSpecV1) Reset() { *m = JamfSpecV1{} } func (m *JamfSpecV1) String() string { return proto.CompactTextString(m) } func (*JamfSpecV1) ProtoMessage() {} func (*JamfSpecV1) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{388} + return fileDescriptor_9198ee693835762e, []int{394} } func (m *JamfSpecV1) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23082,7 +23359,7 @@ func (m *JamfInventoryEntry) Reset() { *m = JamfInventoryEntry{} } func (m *JamfInventoryEntry) String() string { return proto.CompactTextString(m) } func (*JamfInventoryEntry) ProtoMessage() {} func (*JamfInventoryEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{389} + return fileDescriptor_9198ee693835762e, []int{395} } func (m *JamfInventoryEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23139,7 +23416,7 @@ type MessageWithHeader struct { func (m *MessageWithHeader) Reset() { *m = MessageWithHeader{} } func (*MessageWithHeader) ProtoMessage() {} func (*MessageWithHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{390} + return fileDescriptor_9198ee693835762e, []int{396} } func (m *MessageWithHeader) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23203,7 +23480,7 @@ func (m *AWSMatcher) Reset() { *m = AWSMatcher{} } func (m *AWSMatcher) String() string { return proto.CompactTextString(m) } func (*AWSMatcher) ProtoMessage() {} func (*AWSMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{391} + return fileDescriptor_9198ee693835762e, []int{397} } func (m *AWSMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23248,7 +23525,7 @@ func (m *AssumeRole) Reset() { *m = AssumeRole{} } func (m *AssumeRole) String() string { return proto.CompactTextString(m) } func (*AssumeRole) ProtoMessage() {} func (*AssumeRole) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{392} + return fileDescriptor_9198ee693835762e, []int{398} } func (m *AssumeRole) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23310,7 +23587,7 @@ func (m *InstallerParams) Reset() { *m = InstallerParams{} } func (m *InstallerParams) String() string { return proto.CompactTextString(m) } func (*InstallerParams) ProtoMessage() {} func (*InstallerParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{393} + return fileDescriptor_9198ee693835762e, []int{399} } func (m *InstallerParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23353,7 +23630,7 @@ func (m *AWSSSM) Reset() { *m = AWSSSM{} } func (m *AWSSSM) String() string { return proto.CompactTextString(m) } func (*AWSSSM) ProtoMessage() {} func (*AWSSSM) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{394} + return fileDescriptor_9198ee693835762e, []int{400} } func (m *AWSSSM) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23396,7 +23673,7 @@ func (m *AzureInstallerParams) Reset() { *m = AzureInstallerParams{} } func (m *AzureInstallerParams) String() string { return proto.CompactTextString(m) } func (*AzureInstallerParams) ProtoMessage() {} func (*AzureInstallerParams) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{395} + return fileDescriptor_9198ee693835762e, []int{401} } func (m *AzureInstallerParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23450,7 +23727,7 @@ func (m *AzureMatcher) Reset() { *m = AzureMatcher{} } func (m *AzureMatcher) String() string { return proto.CompactTextString(m) } func (*AzureMatcher) ProtoMessage() {} func (*AzureMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{396} + return fileDescriptor_9198ee693835762e, []int{402} } func (m *AzureMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23505,7 +23782,7 @@ func (m *GCPMatcher) Reset() { *m = GCPMatcher{} } func (m *GCPMatcher) String() string { return proto.CompactTextString(m) } func (*GCPMatcher) ProtoMessage() {} func (*GCPMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{397} + return fileDescriptor_9198ee693835762e, []int{403} } func (m *GCPMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23551,7 +23828,7 @@ func (m *KubernetesMatcher) Reset() { *m = KubernetesMatcher{} } func (m *KubernetesMatcher) String() string { return proto.CompactTextString(m) } func (*KubernetesMatcher) ProtoMessage() {} func (*KubernetesMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{398} + return fileDescriptor_9198ee693835762e, []int{404} } func (m *KubernetesMatcher) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23593,7 +23870,7 @@ func (m *OktaOptions) Reset() { *m = OktaOptions{} } func (m *OktaOptions) String() string { return proto.CompactTextString(m) } func (*OktaOptions) ProtoMessage() {} func (*OktaOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{399} + return fileDescriptor_9198ee693835762e, []int{405} } func (m *OktaOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23639,7 +23916,7 @@ func (m *AccessGraphSync) Reset() { *m = AccessGraphSync{} } func (m *AccessGraphSync) String() string { return proto.CompactTextString(m) } func (*AccessGraphSync) ProtoMessage() {} func (*AccessGraphSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{400} + return fileDescriptor_9198ee693835762e, []int{406} } func (m *AccessGraphSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23684,7 +23961,7 @@ func (m *AccessGraphAWSSyncCloudTrailLogs) Reset() { *m = AccessGraphAWS func (m *AccessGraphAWSSyncCloudTrailLogs) String() string { return proto.CompactTextString(m) } func (*AccessGraphAWSSyncCloudTrailLogs) ProtoMessage() {} func (*AccessGraphAWSSyncCloudTrailLogs) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{401} + return fileDescriptor_9198ee693835762e, []int{407} } func (m *AccessGraphAWSSyncCloudTrailLogs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23732,7 +24009,7 @@ func (m *AccessGraphAWSSync) Reset() { *m = AccessGraphAWSSync{} } func (m *AccessGraphAWSSync) String() string { return proto.CompactTextString(m) } func (*AccessGraphAWSSync) ProtoMessage() {} func (*AccessGraphAWSSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{402} + return fileDescriptor_9198ee693835762e, []int{408} } func (m *AccessGraphAWSSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23776,7 +24053,7 @@ func (m *AccessGraphAzureSync) Reset() { *m = AccessGraphAzureSync{} } func (m *AccessGraphAzureSync) String() string { return proto.CompactTextString(m) } func (*AccessGraphAzureSync) ProtoMessage() {} func (*AccessGraphAzureSync) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{403} + return fileDescriptor_9198ee693835762e, []int{409} } func (m *AccessGraphAzureSync) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23832,7 +24109,7 @@ func (m *TargetHealth) Reset() { *m = TargetHealth{} } func (m *TargetHealth) String() string { return proto.CompactTextString(m) } func (*TargetHealth) ProtoMessage() {} func (*TargetHealth) Descriptor() ([]byte, []int) { - return fileDescriptor_9198ee693835762e, []int{404} + return fileDescriptor_9198ee693835762e, []int{410} } func (m *TargetHealth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23965,6 +24242,8 @@ func init() { proto.RegisterType((*SSHKeyPair)(nil), "types.SSHKeyPair") proto.RegisterType((*TLSKeyPair)(nil), "types.TLSKeyPair") proto.RegisterType((*JWTKeyPair)(nil), "types.JWTKeyPair") + proto.RegisterType((*EncryptionKeyPair)(nil), "types.EncryptionKeyPair") + proto.RegisterType((*AgeEncryptionKey)(nil), "types.AgeEncryptionKey") proto.RegisterType((*CertAuthorityV2)(nil), "types.CertAuthorityV2") proto.RegisterType((*CertAuthoritySpecV2)(nil), "types.CertAuthoritySpecV2") proto.RegisterType((*CAKeySet)(nil), "types.CAKeySet") @@ -24017,7 +24296,11 @@ func init() { proto.RegisterType((*AgentMeshTunnelStrategy)(nil), "types.AgentMeshTunnelStrategy") proto.RegisterType((*ProxyPeeringTunnelStrategy)(nil), "types.ProxyPeeringTunnelStrategy") proto.RegisterType((*SessionRecordingConfigV2)(nil), "types.SessionRecordingConfigV2") + proto.RegisterType((*KeyLabel)(nil), "types.KeyLabel") + proto.RegisterType((*ManualKeyManagementConfig)(nil), "types.ManualKeyManagementConfig") + proto.RegisterType((*SessionRecordingEncryptionConfig)(nil), "types.SessionRecordingEncryptionConfig") proto.RegisterType((*SessionRecordingConfigSpecV2)(nil), "types.SessionRecordingConfigSpecV2") + proto.RegisterType((*SessionRecordingConfigStatus)(nil), "types.SessionRecordingConfigStatus") proto.RegisterType((*AuthPreferenceV2)(nil), "types.AuthPreferenceV2") proto.RegisterType((*AuthPreferenceSpecV2)(nil), "types.AuthPreferenceSpecV2") proto.RegisterType((*StableUNIXUserConfig)(nil), "types.StableUNIXUserConfig") @@ -24346,2134 +24629,2153 @@ func init() { func init() { proto.RegisterFile("teleport/legacy/types/types.proto", fileDescriptor_9198ee693835762e) } var fileDescriptor_9198ee693835762e = []byte{ - // 34028 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xfd, 0x7d, 0x6c, 0x5c, 0x59, - 0x76, 0x18, 0x88, 0x4f, 0x55, 0xf1, 0xa3, 0x78, 0x58, 0x24, 0x8b, 0x97, 0x94, 0x44, 0xb1, 0x5b, - 0x4d, 0xf5, 0xeb, 0x6e, 0xb5, 0xd4, 0xd3, 0x2d, 0x8d, 0xa8, 0x69, 0xcd, 0xf4, 0xf7, 0x14, 0x59, - 0x94, 0x54, 0x12, 0x29, 0x55, 0xbf, 0x22, 0xa5, 0x1e, 0xcf, 0xc7, 0x9b, 0xc7, 0xaa, 0x4b, 0xf2, - 0x35, 0xab, 0xde, 0xab, 0x79, 0xef, 0x95, 0x24, 0x7a, 0xe2, 0x5f, 0xe2, 0x5f, 0x3c, 0xeb, 0x18, - 0xde, 0xf1, 0x57, 0xec, 0x78, 0xb2, 0x48, 0x0c, 0xc3, 0xb1, 0x17, 0xd9, 0x04, 0xf6, 0x6e, 0xec, - 0x64, 0x37, 0x0b, 0x23, 0xce, 0x78, 0x11, 0x3b, 0xde, 0x60, 0xb1, 0x36, 0x92, 0x5d, 0x6c, 0x76, - 0x60, 0xd0, 0x48, 0x1c, 0x2c, 0x16, 0x04, 0x16, 0x70, 0x76, 0x81, 0x05, 0x76, 0x8c, 0x60, 0x17, - 0xf7, 0xdc, 0x7b, 0xdf, 0xbb, 0xf7, 0xbd, 0x57, 0xc5, 0x62, 0xb7, 0xda, 0xb1, 0x06, 0xfe, 0x47, - 0x62, 0x9d, 0x7b, 0xce, 0xb9, 0xef, 0x7e, 0x9f, 0x7b, 0xee, 0xf9, 0x80, 0xe7, 0x43, 0xda, 0xa6, - 0x5d, 0xcf, 0x0f, 0xaf, 0xb4, 0xe9, 0xae, 0xdd, 0x3c, 0xb8, 0x12, 0x1e, 0x74, 0x69, 0xc0, 0xff, - 0xbd, 0xdc, 0xf5, 0xbd, 0xd0, 0x23, 0xa3, 0xf8, 0x63, 0x71, 0x7e, 0xd7, 0xdb, 0xf5, 0x10, 0x72, - 0x85, 0xfd, 0xc5, 0x0b, 0x17, 0x9f, 0xdb, 0xf5, 0xbc, 0xdd, 0x36, 0xbd, 0x82, 0xbf, 0xb6, 0x7b, - 0x3b, 0x57, 0x5a, 0x3d, 0xdf, 0x0e, 0x1d, 0xcf, 0x15, 0xe5, 0x4b, 0xc9, 0xf2, 0xd0, 0xe9, 0xd0, - 0x20, 0xb4, 0x3b, 0xdd, 0x7e, 0x0c, 0x1e, 0xf9, 0x76, 0xb7, 0x4b, 0x7d, 0x51, 0xfb, 0xe2, 0xa5, - 0xe8, 0x03, 0xed, 0x30, 0x64, 0x94, 0x8c, 0xf9, 0x95, 0x87, 0x57, 0xd5, 0x9f, 0x02, 0xf5, 0x7a, - 0x9f, 0xb6, 0xf8, 0xbd, 0x20, 0xa4, 0x2d, 0xab, 0x45, 0x1f, 0x3a, 0x4d, 0x6a, 0xf9, 0xf4, 0xeb, - 0x3d, 0xc7, 0xa7, 0x1d, 0xea, 0x86, 0x82, 0xee, 0xb5, 0x6c, 0x3a, 0xf9, 0x21, 0x89, 0x2f, 0x32, - 0x7e, 0xa1, 0x00, 0x13, 0x77, 0x28, 0xed, 0x56, 0xda, 0xce, 0x43, 0x4a, 0x5e, 0x80, 0x91, 0xbb, - 0x76, 0x87, 0x2e, 0xe4, 0xce, 0xe7, 0x2e, 0x4e, 0xac, 0xcc, 0x1c, 0x1d, 0x2e, 0x4d, 0x06, 0xd4, - 0x7f, 0x48, 0x7d, 0xcb, 0xb5, 0x3b, 0xd4, 0xc4, 0x42, 0xf2, 0x69, 0x98, 0x60, 0xff, 0x07, 0x5d, - 0xbb, 0x49, 0x17, 0xf2, 0x88, 0x39, 0x75, 0x74, 0xb8, 0x34, 0xe1, 0x4a, 0xa0, 0x19, 0x97, 0x93, - 0x1a, 0x8c, 0xaf, 0x3d, 0xee, 0x3a, 0x3e, 0x0d, 0x16, 0x46, 0xce, 0xe7, 0x2e, 0x4e, 0x2e, 0x2f, - 0x5e, 0xe6, 0x7d, 0x74, 0x59, 0xf6, 0xd1, 0xe5, 0x4d, 0xd9, 0x89, 0x2b, 0x73, 0xbf, 0x77, 0xb8, - 0xf4, 0xa9, 0xa3, 0xc3, 0xa5, 0x71, 0xca, 0x49, 0x7e, 0xea, 0x8f, 0x96, 0x72, 0xa6, 0xa4, 0x27, - 0x6f, 0xc3, 0xc8, 0xe6, 0x41, 0x97, 0x2e, 0x4c, 0x9c, 0xcf, 0x5d, 0x9c, 0x5e, 0x7e, 0xee, 0x32, - 0x1f, 0xd6, 0xe8, 0xe3, 0xe3, 0xbf, 0x18, 0xd6, 0x4a, 0xf1, 0xe8, 0x70, 0x69, 0x84, 0xa1, 0x98, - 0x48, 0x45, 0x5e, 0x83, 0xb1, 0x5b, 0x5e, 0x10, 0xd6, 0xaa, 0x0b, 0x80, 0x9f, 0x7c, 0xea, 0xe8, - 0x70, 0x69, 0x76, 0xcf, 0x0b, 0x42, 0xcb, 0x69, 0xbd, 0xea, 0x75, 0x9c, 0x90, 0x76, 0xba, 0xe1, - 0x81, 0x29, 0x90, 0x8c, 0xc7, 0x30, 0xa5, 0xf1, 0x23, 0x93, 0x30, 0xbe, 0x75, 0xf7, 0xce, 0xdd, - 0x7b, 0x0f, 0xee, 0x96, 0x3f, 0x45, 0x8a, 0x30, 0x72, 0xf7, 0x5e, 0x75, 0xad, 0x9c, 0x23, 0xe3, - 0x50, 0xa8, 0xd4, 0xeb, 0xe5, 0x3c, 0x29, 0x41, 0xb1, 0x5a, 0xd9, 0xac, 0xac, 0x54, 0x1a, 0x6b, - 0xe5, 0x02, 0x99, 0x83, 0x99, 0x07, 0xb5, 0xbb, 0xd5, 0x7b, 0x0f, 0x1a, 0x56, 0x75, 0xad, 0x71, - 0x67, 0xf3, 0x5e, 0xbd, 0x3c, 0x42, 0xa6, 0x01, 0xee, 0x6c, 0xad, 0xac, 0x99, 0x77, 0xd7, 0x36, - 0xd7, 0x1a, 0xe5, 0x51, 0x32, 0x0f, 0x65, 0x49, 0x62, 0x35, 0xd6, 0xcc, 0xfb, 0xb5, 0xd5, 0xb5, - 0xf2, 0xd8, 0xed, 0x91, 0x62, 0xa1, 0x3c, 0x62, 0x8e, 0xaf, 0x53, 0x3b, 0xa0, 0xb5, 0xaa, 0xf1, - 0x77, 0x0a, 0x50, 0xdc, 0xa0, 0xa1, 0xdd, 0xb2, 0x43, 0x9b, 0x3c, 0xab, 0x8d, 0x0f, 0x36, 0x51, - 0x19, 0x98, 0x17, 0xd2, 0x03, 0x33, 0x7a, 0x74, 0xb8, 0x94, 0x7b, 0x4d, 0x1d, 0x90, 0xb7, 0x60, - 0xb2, 0x4a, 0x83, 0xa6, 0xef, 0x74, 0xd9, 0x64, 0x5b, 0x28, 0x20, 0xda, 0xd9, 0xa3, 0xc3, 0xa5, - 0x53, 0xad, 0x18, 0xac, 0x74, 0x88, 0x8a, 0x4d, 0x6a, 0x30, 0xb6, 0x6e, 0x6f, 0xd3, 0x76, 0xb0, - 0x30, 0x7a, 0xbe, 0x70, 0x71, 0x72, 0xf9, 0x19, 0x31, 0x08, 0xf2, 0x03, 0x2f, 0xf3, 0xd2, 0x35, - 0x37, 0xf4, 0x0f, 0x56, 0xe6, 0x8f, 0x0e, 0x97, 0xca, 0x6d, 0x04, 0xa8, 0x1d, 0xcc, 0x51, 0x48, - 0x23, 0x9e, 0x18, 0x63, 0xc7, 0x4e, 0x8c, 0x73, 0xbf, 0x77, 0xb8, 0x94, 0x63, 0x03, 0x26, 0x26, - 0x46, 0xcc, 0x4f, 0x9f, 0x22, 0xcb, 0x50, 0x34, 0xe9, 0x43, 0x27, 0x60, 0x2d, 0x2b, 0x62, 0xcb, - 0x4e, 0x1f, 0x1d, 0x2e, 0x11, 0x5f, 0xc0, 0x94, 0xcf, 0x88, 0xf0, 0x16, 0xdf, 0x80, 0x49, 0xe5, - 0xab, 0x49, 0x19, 0x0a, 0xfb, 0xf4, 0x80, 0xf7, 0xb0, 0xc9, 0xfe, 0x24, 0xf3, 0x30, 0xfa, 0xd0, - 0x6e, 0xf7, 0x44, 0x97, 0x9a, 0xfc, 0xc7, 0x9b, 0xf9, 0xcf, 0xe7, 0x6e, 0x8f, 0x14, 0xc7, 0xcb, - 0x45, 0x33, 0x5f, 0xab, 0x1a, 0x3f, 0x33, 0x02, 0x45, 0xd3, 0xe3, 0x0b, 0x98, 0x5c, 0x82, 0xd1, - 0x46, 0x68, 0x87, 0x72, 0x98, 0xe6, 0x8e, 0x0e, 0x97, 0x66, 0xd8, 0xe2, 0xa6, 0x4a, 0xfd, 0x1c, - 0x83, 0xa1, 0xd6, 0xf7, 0xec, 0x40, 0x0e, 0x17, 0xa2, 0x76, 0x19, 0x40, 0x45, 0x45, 0x0c, 0x72, - 0x01, 0x46, 0x36, 0xbc, 0x16, 0x15, 0x23, 0x46, 0x8e, 0x0e, 0x97, 0xa6, 0x3b, 0x5e, 0x4b, 0x45, - 0xc4, 0x72, 0xf2, 0x2a, 0x4c, 0xac, 0xf6, 0x7c, 0x9f, 0xba, 0x6c, 0xae, 0x8f, 0x20, 0xf2, 0xf4, - 0xd1, 0xe1, 0x12, 0x34, 0x39, 0xd0, 0x72, 0x5a, 0x66, 0x8c, 0xc0, 0x86, 0xa1, 0x11, 0xda, 0x7e, - 0x48, 0x5b, 0x0b, 0xa3, 0x43, 0x0d, 0x03, 0x5b, 0x9f, 0xb3, 0x01, 0x27, 0x49, 0x0e, 0x83, 0xe0, - 0x44, 0x6e, 0xc1, 0xe4, 0x4d, 0xdf, 0x6e, 0xd2, 0x3a, 0xf5, 0x1d, 0xaf, 0x85, 0xe3, 0x5b, 0x58, - 0xb9, 0x70, 0x74, 0xb8, 0x74, 0x7a, 0x97, 0x81, 0xad, 0x2e, 0xc2, 0x63, 0xea, 0xef, 0x1d, 0x2e, - 0x15, 0xab, 0x62, 0xab, 0x35, 0x55, 0x52, 0xf2, 0x35, 0x36, 0x38, 0x41, 0x88, 0x5d, 0x4b, 0x5b, - 0x0b, 0xe3, 0xc7, 0x7e, 0xa2, 0x21, 0x3e, 0xf1, 0x74, 0xdb, 0x0e, 0x42, 0xcb, 0xe7, 0x74, 0x89, - 0xef, 0x54, 0x59, 0x92, 0x7b, 0x50, 0x6c, 0x34, 0xf7, 0x68, 0xab, 0xd7, 0xa6, 0x38, 0x65, 0x26, - 0x97, 0xcf, 0x88, 0x49, 0x2d, 0xc7, 0x53, 0x16, 0xaf, 0x2c, 0x0a, 0xde, 0x24, 0x10, 0x10, 0x75, - 0x3e, 0x49, 0xac, 0x37, 0x8b, 0xdf, 0xfe, 0xc5, 0xa5, 0x4f, 0xfd, 0x95, 0x3f, 0x3c, 0xff, 0x29, - 0xe3, 0xbf, 0xc9, 0x43, 0x39, 0xc9, 0x84, 0xec, 0xc0, 0xd4, 0x56, 0xb7, 0x65, 0x87, 0x74, 0xb5, - 0xed, 0x50, 0x37, 0x0c, 0x70, 0x92, 0x0c, 0x6e, 0xd3, 0x8b, 0xa2, 0xde, 0x85, 0x1e, 0x12, 0x5a, - 0x4d, 0x4e, 0x99, 0x68, 0x95, 0xce, 0x36, 0xae, 0xa7, 0x81, 0x1b, 0x78, 0x80, 0x33, 0xec, 0x64, - 0xf5, 0xf0, 0xad, 0xbf, 0x4f, 0x3d, 0x82, 0xad, 0x98, 0x40, 0x6e, 0x6b, 0xfb, 0x00, 0x67, 0xe6, - 0xf0, 0x13, 0x88, 0x91, 0x64, 0x4c, 0x20, 0x06, 0x36, 0xfe, 0x5d, 0x0e, 0xa6, 0x4d, 0x1a, 0x78, - 0x3d, 0xbf, 0x49, 0x6f, 0x51, 0xbb, 0x45, 0x7d, 0x36, 0xfd, 0xef, 0x38, 0x6e, 0x4b, 0xac, 0x29, - 0x9c, 0xfe, 0xfb, 0x8e, 0xab, 0x6e, 0xdd, 0x58, 0x4e, 0x3e, 0x03, 0xe3, 0x8d, 0xde, 0x36, 0xa2, - 0xe6, 0xe3, 0x1d, 0x20, 0xe8, 0x6d, 0x5b, 0x09, 0x74, 0x89, 0x46, 0xae, 0xc0, 0xf8, 0x7d, 0xea, - 0x07, 0xf1, 0x6e, 0x88, 0x47, 0xc3, 0x43, 0x0e, 0x52, 0x09, 0x04, 0x16, 0xb9, 0x19, 0xef, 0xc8, - 0xe2, 0x50, 0x9b, 0x49, 0xec, 0x83, 0xf1, 0x54, 0xe9, 0x08, 0x88, 0x3a, 0x55, 0x24, 0x96, 0xf1, - 0xaf, 0xf3, 0x50, 0xae, 0xda, 0xa1, 0xbd, 0x6d, 0x07, 0xa2, 0x3f, 0xef, 0x5f, 0x63, 0x7b, 0xbc, - 0xd2, 0x50, 0xdc, 0xe3, 0xd9, 0x97, 0x7f, 0xe4, 0xe6, 0xbd, 0x94, 0x6c, 0xde, 0x24, 0x3b, 0x61, - 0x45, 0xf3, 0xe2, 0x46, 0xbd, 0x73, 0x7c, 0xa3, 0xca, 0xa2, 0x51, 0x45, 0xd9, 0xa8, 0xb8, 0x29, - 0xe4, 0x1d, 0x18, 0x69, 0x74, 0x69, 0x53, 0x6c, 0x22, 0xf2, 0x5c, 0xd0, 0x1b, 0xc7, 0x10, 0xee, - 0x5f, 0x5b, 0x29, 0x09, 0x36, 0x23, 0x41, 0x97, 0x36, 0x4d, 0x24, 0x23, 0x6b, 0x30, 0xc6, 0x36, - 0xc4, 0x9e, 0x3c, 0x0c, 0xce, 0x65, 0x33, 0x40, 0x94, 0xfb, 0xd7, 0x56, 0xa6, 0x05, 0x8b, 0xb1, - 0x00, 0x21, 0xa6, 0x20, 0x56, 0xd6, 0xde, 0x3f, 0x2e, 0xc0, 0x7c, 0x56, 0xed, 0x6a, 0x77, 0x8c, - 0x0d, 0xe8, 0x8e, 0x8b, 0x50, 0x64, 0x92, 0x00, 0x3b, 0x5d, 0x71, 0xd7, 0x99, 0x58, 0x29, 0xb1, - 0x96, 0xef, 0x09, 0x98, 0x19, 0x95, 0x92, 0x17, 0x22, 0xc1, 0xa2, 0x18, 0xf3, 0x13, 0x82, 0x85, - 0x14, 0x27, 0xd8, 0x94, 0x91, 0x3b, 0x01, 0xca, 0x1f, 0x71, 0xef, 0x4a, 0x70, 0x3c, 0x65, 0x7c, - 0x01, 0xd1, 0x4e, 0x2b, 0x79, 0xb6, 0xac, 0x41, 0x51, 0x36, 0x6b, 0xa1, 0x84, 0x8c, 0x66, 0x13, - 0x5d, 0x75, 0xff, 0x1a, 0x9f, 0x13, 0x2d, 0xf1, 0x5b, 0x65, 0x23, 0x71, 0xc8, 0x35, 0x28, 0xd6, - 0x7d, 0xef, 0xf1, 0x41, 0xad, 0x1a, 0x2c, 0x4c, 0x9d, 0x2f, 0x5c, 0x9c, 0x58, 0x39, 0x73, 0x74, - 0xb8, 0x34, 0xd7, 0x65, 0x30, 0xcb, 0x69, 0xa9, 0x07, 0x76, 0x84, 0x78, 0x7b, 0xa4, 0x98, 0x2b, - 0xe7, 0x6f, 0x8f, 0x14, 0xf3, 0xe5, 0x02, 0x97, 0x52, 0x6e, 0x8f, 0x14, 0x47, 0xca, 0xa3, 0xb7, - 0x47, 0x8a, 0xa3, 0x28, 0xb7, 0x4c, 0x94, 0xe1, 0xf6, 0x48, 0x71, 0xb2, 0x5c, 0xd2, 0x84, 0x06, - 0x64, 0x10, 0x7a, 0x4d, 0xaf, 0x6d, 0x16, 0xb6, 0xcc, 0x9a, 0x39, 0xb6, 0x5a, 0x59, 0xa5, 0x7e, - 0x68, 0x16, 0x2a, 0x0f, 0x1a, 0xe6, 0x54, 0xf5, 0xc0, 0xb5, 0x3b, 0x4e, 0x93, 0x9f, 0xc0, 0x66, - 0xe1, 0xe6, 0x6a, 0xdd, 0x70, 0xe1, 0x74, 0xf6, 0xb0, 0x93, 0x4d, 0x28, 0x6d, 0xda, 0xfe, 0x2e, - 0x0d, 0x6f, 0x51, 0xbb, 0x1d, 0xee, 0x2d, 0x4c, 0x63, 0x07, 0xcc, 0x89, 0x0e, 0x50, 0x8b, 0x56, - 0x9e, 0x39, 0x3a, 0x5c, 0x3a, 0x13, 0x22, 0xc4, 0xda, 0x43, 0x90, 0xd2, 0x24, 0x8d, 0x8b, 0x51, - 0x81, 0xe9, 0xb8, 0xef, 0xd6, 0x9d, 0x20, 0x24, 0x57, 0x60, 0x42, 0x42, 0xd8, 0xfe, 0x5c, 0xc8, - 0xec, 0x65, 0x33, 0xc6, 0x31, 0x7e, 0x37, 0x0f, 0x10, 0x97, 0x3c, 0xa5, 0x4b, 0xf8, 0x73, 0xda, - 0x12, 0x3e, 0x95, 0x5c, 0x81, 0xfd, 0x17, 0xef, 0x7b, 0x89, 0xc5, 0x7b, 0x26, 0x49, 0x3a, 0xfc, - 0xb2, 0xfd, 0x85, 0xf1, 0x78, 0x30, 0xc4, 0x82, 0xbd, 0x08, 0xd1, 0x04, 0x12, 0x1d, 0x8a, 0x2b, - 0xb1, 0x2b, 0x27, 0x55, 0x54, 0x4a, 0xce, 0x02, 0x9b, 0x60, 0xa2, 0x53, 0xc7, 0x8f, 0x0e, 0x97, - 0x0a, 0x3d, 0xdf, 0xc1, 0x49, 0x47, 0xae, 0x80, 0x98, 0x76, 0xa2, 0x03, 0xd9, 0x6c, 0x9f, 0x6d, - 0xda, 0x56, 0x93, 0xfa, 0x61, 0xdc, 0xe3, 0x0b, 0x39, 0x39, 0x3b, 0x49, 0x17, 0xf4, 0xa9, 0xb9, - 0x30, 0x82, 0xd3, 0xe0, 0x62, 0x66, 0xaf, 0x5c, 0xd6, 0x50, 0xb9, 0xf4, 0x7b, 0x5e, 0x1e, 0xa6, - 0x2d, 0x5e, 0x66, 0xa5, 0x24, 0x61, 0xbd, 0x02, 0x72, 0x0d, 0xd8, 0x8a, 0x10, 0xbd, 0x0f, 0xa2, - 0x9e, 0xca, 0x83, 0xc6, 0xca, 0x29, 0xc1, 0x69, 0xca, 0x7e, 0xa4, 0x92, 0x33, 0x6c, 0xf2, 0x16, - 0xb0, 0x25, 0x23, 0xfa, 0x9d, 0x08, 0xa2, 0x9b, 0xab, 0xf5, 0xd5, 0xb6, 0xd7, 0x6b, 0x35, 0xde, - 0x5f, 0x8f, 0x89, 0x77, 0x9b, 0x5d, 0x95, 0xf8, 0xe6, 0x6a, 0x9d, 0xbc, 0x05, 0xa3, 0x95, 0x1f, - 0xec, 0xf9, 0x54, 0x88, 0x55, 0x25, 0x59, 0x27, 0x83, 0xad, 0x9c, 0x11, 0x84, 0x33, 0x36, 0xfb, - 0xa9, 0x8a, 0xa3, 0x58, 0xce, 0x6a, 0xde, 0x5c, 0x6f, 0x08, 0x91, 0x89, 0x24, 0xba, 0x65, 0x73, - 0x5d, 0xf9, 0xec, 0x50, 0x6b, 0x35, 0xa3, 0x22, 0x57, 0x20, 0x5f, 0xa9, 0xe2, 0x45, 0x6e, 0x72, - 0x79, 0x42, 0x56, 0x5b, 0x5d, 0x99, 0x17, 0x24, 0x25, 0x5b, 0x5d, 0x06, 0xf9, 0x4a, 0x95, 0xac, - 0xc0, 0xe8, 0xc6, 0x41, 0xe3, 0xfd, 0x75, 0xb1, 0x79, 0xca, 0x25, 0x8f, 0xb0, 0x7b, 0xb8, 0xcd, - 0x04, 0xf1, 0x17, 0x77, 0x0e, 0x82, 0xaf, 0xb7, 0xd5, 0x2f, 0x46, 0x34, 0x52, 0x87, 0x89, 0x4a, - 0xab, 0xe3, 0xb8, 0x5b, 0x01, 0xf5, 0x17, 0x26, 0x91, 0xcf, 0x42, 0xe2, 0xbb, 0xa3, 0xf2, 0x95, - 0x85, 0xa3, 0xc3, 0xa5, 0x79, 0x9b, 0xfd, 0xb4, 0x7a, 0x01, 0xf5, 0x15, 0x6e, 0x31, 0x13, 0x52, - 0x07, 0xd8, 0xf0, 0xdc, 0x5d, 0xaf, 0x12, 0xb6, 0xed, 0x20, 0xb1, 0x1d, 0xc7, 0x05, 0x91, 0xd4, - 0x73, 0xaa, 0xc3, 0x60, 0x96, 0xcd, 0x80, 0x0a, 0x43, 0x85, 0x07, 0xb9, 0x01, 0x63, 0xf7, 0x7c, - 0xbb, 0xd9, 0xa6, 0x0b, 0x53, 0xc8, 0x6d, 0x5e, 0x70, 0xe3, 0x40, 0xd9, 0xd2, 0x05, 0xc1, 0xb0, - 0xec, 0x21, 0x58, 0xbd, 0x5d, 0x71, 0xc4, 0xc5, 0x07, 0x40, 0xd2, 0x73, 0x32, 0xe3, 0x6e, 0xf3, - 0x69, 0xf5, 0x6e, 0x13, 0x2f, 0xfa, 0x55, 0xaf, 0xd3, 0xb1, 0xdd, 0x16, 0xd2, 0xde, 0x5f, 0x56, - 0xae, 0x3c, 0xc6, 0xd7, 0x61, 0x36, 0xd5, 0x59, 0xc7, 0x5c, 0x4b, 0xdf, 0x85, 0x99, 0x2a, 0xdd, - 0xb1, 0x7b, 0xed, 0x30, 0x3a, 0xb9, 0xf8, 0x12, 0xc5, 0x0b, 0x62, 0x8b, 0x17, 0x59, 0xf2, 0xb8, - 0x32, 0x93, 0xc8, 0xc6, 0x3b, 0x30, 0xa5, 0x35, 0x9f, 0xdd, 0x70, 0x2a, 0xbd, 0x96, 0x13, 0xe2, - 0x40, 0xe6, 0xe2, 0x1b, 0x8e, 0xcd, 0x80, 0x38, 0x5c, 0x66, 0x8c, 0x60, 0xfc, 0xb2, 0x2a, 0x64, - 0xc9, 0x93, 0xe4, 0xb5, 0x68, 0x3f, 0xc8, 0xc5, 0x22, 0x5f, 0x6a, 0x3f, 0x88, 0x76, 0x83, 0x4b, - 0x7c, 0x6d, 0xe6, 0x53, 0x6b, 0x73, 0x52, 0x8c, 0x44, 0xc1, 0x7e, 0x14, 0xf0, 0x15, 0x19, 0xcd, - 0xd4, 0xc2, 0x47, 0x9f, 0xa9, 0xef, 0x41, 0x69, 0xc3, 0x76, 0xed, 0x5d, 0xda, 0x62, 0x2d, 0xe0, - 0x7b, 0xcf, 0x04, 0x3f, 0xd2, 0x3a, 0x1c, 0x8e, 0xad, 0x54, 0x27, 0x91, 0x46, 0x40, 0xae, 0xca, - 0x95, 0x3d, 0x9a, 0xb1, 0xb2, 0xa7, 0x44, 0xed, 0xa3, 0xb8, 0xb2, 0xc5, 0x7a, 0x36, 0xbe, 0x33, - 0x81, 0x6d, 0x24, 0xaf, 0xc2, 0x98, 0x49, 0x77, 0xd9, 0x51, 0x93, 0x8b, 0x07, 0xc9, 0x47, 0x88, - 0xda, 0x31, 0x1c, 0x07, 0xe5, 0x1a, 0xda, 0x0a, 0xf6, 0x9c, 0x9d, 0x50, 0xf4, 0x4e, 0x24, 0xd7, - 0x08, 0xb0, 0x22, 0xd7, 0x08, 0x88, 0x7e, 0x0b, 0xe7, 0x30, 0xb6, 0xfb, 0x99, 0xd5, 0x86, 0xe8, - 0x34, 0xd9, 0xc3, 0x66, 0x55, 0xd9, 0x46, 0x7c, 0x4d, 0x2a, 0x61, 0xd8, 0xe4, 0x3a, 0x4c, 0x54, - 0x9a, 0x4d, 0xaf, 0xa7, 0x5c, 0x75, 0xf9, 0xba, 0xe5, 0x40, 0x5d, 0xb3, 0x13, 0xa3, 0x92, 0x06, - 0x4c, 0xae, 0xb1, 0xfb, 0xa1, 0xb3, 0x6a, 0x37, 0xf7, 0x64, 0x27, 0xc9, 0x3d, 0x4c, 0x29, 0x89, - 0x57, 0x2e, 0x45, 0x60, 0x93, 0x01, 0x55, 0xdd, 0x88, 0x82, 0x4b, 0x36, 0x61, 0xb2, 0x41, 0x9b, - 0x3e, 0x0d, 0x1b, 0xa1, 0xe7, 0xd3, 0xc4, 0x96, 0xac, 0x94, 0xac, 0x3c, 0x27, 0xaf, 0xa8, 0x01, - 0x02, 0xad, 0x80, 0x41, 0x55, 0xae, 0x0a, 0x32, 0xbf, 0x6b, 0x74, 0x3c, 0xff, 0xa0, 0xba, 0x22, - 0xb6, 0xe9, 0xf8, 0x4c, 0xe7, 0x60, 0xf5, 0xae, 0xc1, 0x20, 0xad, 0x6d, 0xfd, 0xae, 0xc1, 0xb1, - 0x70, 0xa4, 0xaa, 0x0d, 0x94, 0xe5, 0xc4, 0xa6, 0x3d, 0x13, 0xf7, 0x32, 0x82, 0x95, 0x91, 0x6a, - 0x05, 0x28, 0x09, 0x6a, 0x23, 0x25, 0xb0, 0x48, 0x17, 0x88, 0x1c, 0x35, 0x2e, 0x9e, 0xb5, 0x69, - 0x10, 0x88, 0xbd, 0xfc, 0x6c, 0x62, 0xf0, 0x63, 0x84, 0x95, 0x97, 0x04, 0xf3, 0x73, 0x72, 0x1a, - 0x88, 0xeb, 0x25, 0x2b, 0x54, 0xea, 0xc9, 0xe0, 0x4d, 0xde, 0x00, 0x58, 0x7b, 0x1c, 0x52, 0xdf, - 0xb5, 0xdb, 0x91, 0xfa, 0x0e, 0x35, 0x56, 0x54, 0x40, 0xf5, 0x81, 0x56, 0x90, 0xc9, 0x2a, 0x4c, - 0x55, 0x82, 0xa0, 0xd7, 0xa1, 0xa6, 0xd7, 0xa6, 0x15, 0xf3, 0x2e, 0xee, 0xfb, 0x13, 0x2b, 0xe7, - 0x8e, 0x0e, 0x97, 0xce, 0xda, 0x58, 0x60, 0xf9, 0x5e, 0x9b, 0x5a, 0xb6, 0xaf, 0xce, 0x6e, 0x9d, - 0x86, 0xdc, 0x03, 0xb8, 0xd7, 0xa5, 0x6e, 0x83, 0xda, 0x7e, 0x73, 0x2f, 0xb1, 0xcd, 0xc7, 0x05, - 0x2b, 0xcf, 0x8a, 0x16, 0xce, 0x7b, 0x5d, 0xea, 0x06, 0x08, 0x53, 0xbf, 0x2a, 0xc6, 0x24, 0x0f, - 0x60, 0xa6, 0x56, 0xd9, 0xa8, 0x7b, 0x6d, 0xa7, 0x79, 0x20, 0x24, 0xa7, 0x69, 0x54, 0x6a, 0x9e, - 0x16, 0x5c, 0x13, 0xa5, 0x7c, 0x7b, 0x72, 0xec, 0x8e, 0xd5, 0x45, 0xa8, 0x25, 0xe4, 0xa7, 0x24, - 0x17, 0xf2, 0x45, 0x36, 0x07, 0x03, 0x26, 0x0c, 0x6e, 0xda, 0xbb, 0xc1, 0xc2, 0x8c, 0xa6, 0xa4, - 0xab, 0x3c, 0x68, 0x5c, 0x56, 0x4a, 0xb9, 0x98, 0xb2, 0xc8, 0x27, 0x22, 0x42, 0xad, 0xd0, 0xde, - 0x0d, 0xf4, 0x89, 0x18, 0x61, 0x93, 0xdb, 0x00, 0x55, 0xaf, 0xd9, 0xeb, 0x50, 0x37, 0xac, 0xae, - 0x2c, 0x94, 0xf5, 0xab, 0x47, 0x54, 0x10, 0x6f, 0x6d, 0x2d, 0xaf, 0xa9, 0xcd, 0x44, 0x85, 0x7a, - 0xf1, 0x5d, 0x28, 0x27, 0x3f, 0xe4, 0x84, 0x7a, 0xb7, 0xa9, 0xf2, 0xb4, 0xd2, 0xfa, 0xb5, 0xc7, - 0x4e, 0x10, 0x06, 0xc6, 0x37, 0xb4, 0x15, 0xc8, 0x76, 0x87, 0x3b, 0xf4, 0xa0, 0xee, 0xd3, 0x1d, - 0xe7, 0xb1, 0xd8, 0xcc, 0x70, 0x77, 0xd8, 0xa7, 0x07, 0x56, 0x17, 0xa1, 0xea, 0xee, 0x10, 0xa1, - 0x92, 0xcf, 0x42, 0xf1, 0xce, 0x46, 0xe3, 0x0e, 0x3d, 0xa8, 0x55, 0xc5, 0x41, 0xc5, 0xc9, 0x3a, - 0x81, 0xc5, 0x48, 0xb5, 0xb9, 0x16, 0x61, 0x1a, 0x2b, 0xf1, 0x4e, 0xc8, 0x6a, 0x5e, 0x6d, 0xf7, - 0x82, 0x90, 0xfa, 0xb5, 0xaa, 0x5a, 0x73, 0x93, 0x03, 0x13, 0xfb, 0x52, 0x84, 0x6a, 0xfc, 0xbf, - 0x79, 0xdc, 0x05, 0xd9, 0x84, 0xaf, 0xb9, 0x41, 0x68, 0xbb, 0x4d, 0x1a, 0x31, 0xc0, 0x09, 0xef, - 0x08, 0x68, 0x62, 0xc2, 0xc7, 0xc8, 0x7a, 0xd5, 0xf9, 0xa1, 0xab, 0x66, 0x55, 0x4a, 0x85, 0x4b, - 0xad, 0xaa, 0x6a, 0x85, 0x7d, 0x01, 0x4d, 0x54, 0x19, 0x23, 0x93, 0x0b, 0x30, 0x5e, 0xab, 0x6c, - 0x54, 0x7a, 0xe1, 0x1e, 0xee, 0xc1, 0x45, 0x2e, 0x9f, 0xb3, 0xd9, 0x6a, 0xf7, 0xc2, 0x3d, 0x53, - 0x16, 0x92, 0x2b, 0x78, 0xef, 0x71, 0x69, 0xc8, 0xb5, 0xc7, 0xe2, 0xd0, 0x0d, 0x38, 0x28, 0x71, - 0xed, 0x61, 0x20, 0xf2, 0x0a, 0x8c, 0xde, 0xaf, 0xaf, 0xd6, 0xaa, 0xe2, 0xa2, 0x8e, 0x27, 0xd1, - 0xc3, 0x6e, 0x53, 0xff, 0x12, 0x8e, 0x42, 0xd6, 0x60, 0xba, 0x41, 0x9b, 0x3d, 0xdf, 0x09, 0x0f, - 0x6e, 0xfa, 0x5e, 0xaf, 0x1b, 0x2c, 0x8c, 0x63, 0x1d, 0xb8, 0xd2, 0x03, 0x51, 0x62, 0xed, 0x62, - 0x91, 0x42, 0x9d, 0x20, 0x32, 0x7e, 0x3b, 0x17, 0x6f, 0x93, 0xe4, 0x82, 0x26, 0xd6, 0xa0, 0xca, - 0x89, 0x89, 0x35, 0xaa, 0xca, 0x09, 0x05, 0x1c, 0x13, 0xc8, 0x6a, 0x2f, 0x08, 0xbd, 0xce, 0x9a, - 0xdb, 0xea, 0x7a, 0x8e, 0x1b, 0x22, 0x15, 0xef, 0x7c, 0xe3, 0xe8, 0x70, 0xe9, 0xb9, 0x26, 0x96, - 0x5a, 0x54, 0x14, 0x5b, 0x09, 0x2e, 0x19, 0xd4, 0x1f, 0x63, 0x3c, 0x8c, 0x7f, 0x91, 0xd7, 0x8e, - 0x37, 0xf6, 0x79, 0x26, 0xed, 0xb6, 0x9d, 0x26, 0x6a, 0x10, 0xb0, 0xa1, 0xd1, 0xac, 0xc2, 0xcf, - 0xf3, 0xe3, 0x52, 0xde, 0x43, 0x3a, 0xef, 0x0c, 0x6a, 0xf2, 0x05, 0x28, 0x31, 0x49, 0x43, 0xfc, - 0x0c, 0x16, 0xf2, 0xd8, 0xd9, 0xcf, 0xa2, 0xf2, 0x30, 0xa0, 0x7e, 0xc4, 0x46, 0x13, 0x51, 0x54, - 0x0a, 0xd2, 0x82, 0x85, 0x4d, 0xdf, 0x76, 0x03, 0x27, 0x5c, 0x73, 0x9b, 0xfe, 0x01, 0x4a, 0x46, - 0x6b, 0xae, 0xbd, 0xdd, 0xa6, 0x2d, 0x6c, 0x6e, 0x71, 0xe5, 0xe2, 0xd1, 0xe1, 0xd2, 0x8b, 0x21, - 0xc7, 0xb1, 0x68, 0x84, 0x64, 0x51, 0x8e, 0xa5, 0x70, 0xee, 0xcb, 0x89, 0x49, 0x52, 0xb2, 0x5b, - 0xf1, 0xed, 0x88, 0x0b, 0x09, 0x28, 0x49, 0x45, 0xa3, 0xc1, 0xf6, 0x30, 0xf5, 0x33, 0x55, 0x02, - 0xe3, 0xff, 0xce, 0xc5, 0x07, 0x30, 0x79, 0x1b, 0x26, 0xc5, 0x8a, 0x51, 0xe6, 0x05, 0xee, 0xa0, - 0x72, 0x79, 0x25, 0x46, 0x56, 0x45, 0x67, 0xf7, 0xfe, 0xca, 0xea, 0xba, 0x32, 0x37, 0xf0, 0xde, - 0x6f, 0x37, 0xdb, 0x49, 0x2a, 0x89, 0xc6, 0x26, 0xc1, 0xe6, 0x7a, 0x43, 0xef, 0x15, 0x9c, 0x04, - 0x61, 0x3b, 0xc8, 0xe8, 0x06, 0x05, 0xf9, 0xe3, 0x37, 0xfc, 0x7f, 0xc9, 0x65, 0x9d, 0xf3, 0x64, - 0x05, 0xa6, 0x1e, 0x78, 0xfe, 0x3e, 0x8e, 0xaf, 0xd2, 0x09, 0x38, 0xf2, 0x8f, 0x64, 0x41, 0xb2, - 0x41, 0x3a, 0x89, 0xfa, 0x6d, 0x4a, 0x6f, 0xe8, 0xdf, 0x96, 0xe0, 0xa0, 0x11, 0xb0, 0x71, 0x88, - 0x38, 0x46, 0xab, 0x03, 0xc7, 0x21, 0xfe, 0x04, 0x6d, 0x0a, 0xab, 0xe8, 0xc6, 0x3f, 0xc9, 0xa9, - 0xe7, 0x39, 0xeb, 0xe4, 0xaa, 0xd7, 0xb1, 0x1d, 0x57, 0x69, 0x0e, 0x7f, 0x0f, 0x43, 0x68, 0xf2, - 0x4b, 0x14, 0x64, 0x72, 0x0d, 0x8a, 0xfc, 0x57, 0xb4, 0xd7, 0xa2, 0x16, 0x4d, 0x10, 0xea, 0x07, - 0x85, 0x44, 0x4c, 0x8d, 0x4c, 0xe1, 0xa4, 0x23, 0xf3, 0x9d, 0x9c, 0x7a, 0x14, 0x7f, 0xd4, 0xc3, - 0x26, 0x71, 0xc8, 0xe4, 0x4f, 0x72, 0xc8, 0x7c, 0xec, 0x26, 0xfc, 0x4e, 0x0e, 0x26, 0x15, 0x2d, - 0x05, 0x6b, 0x43, 0xdd, 0xf7, 0x3e, 0xa4, 0xcd, 0x50, 0x6f, 0x43, 0x97, 0x03, 0x13, 0x6d, 0x88, - 0x50, 0x3f, 0x4e, 0x1b, 0x56, 0x61, 0xbc, 0xd2, 0x6e, 0x7b, 0x4c, 0xae, 0xe6, 0x97, 0x8e, 0x69, - 0x29, 0x26, 0x71, 0xe8, 0xca, 0x59, 0xf9, 0x56, 0x61, 0x33, 0x80, 0x26, 0xcb, 0x48, 0x4a, 0xe3, - 0xe7, 0x73, 0x11, 0x97, 0x54, 0xa7, 0xe4, 0x4e, 0xd8, 0x29, 0xe4, 0x0e, 0x94, 0xe5, 0xef, 0x7b, - 0x0f, 0xa9, 0xef, 0x3b, 0x2d, 0xb9, 0x34, 0x96, 0x8e, 0x0e, 0x97, 0x9e, 0x89, 0x98, 0x78, 0xa2, - 0x50, 0x61, 0x94, 0x22, 0x34, 0xfe, 0x7d, 0x4e, 0x5c, 0x01, 0x87, 0x3e, 0xc5, 0xf4, 0x13, 0x27, - 0x7f, 0x12, 0x09, 0xe0, 0x0b, 0x30, 0x6a, 0xd2, 0x96, 0x13, 0x88, 0x9e, 0x9c, 0x55, 0xaf, 0x9b, - 0x58, 0x10, 0x8b, 0x85, 0x3e, 0xfb, 0xa9, 0x1e, 0xdf, 0x58, 0xce, 0xe4, 0xf4, 0x5a, 0x70, 0xa3, - 0x4d, 0x1f, 0x3b, 0x7c, 0xaf, 0x11, 0x92, 0x04, 0x9e, 0xde, 0x4e, 0x60, 0xed, 0xb0, 0x12, 0x71, - 0x61, 0x50, 0xf7, 0x15, 0x8d, 0xc6, 0xf8, 0x22, 0x40, 0x5c, 0x25, 0xeb, 0x4e, 0x31, 0xd9, 0x1d, - 0x77, 0x97, 0xcb, 0x89, 0xa2, 0x0f, 0xb0, 0x3b, 0x9b, 0x51, 0x99, 0x10, 0xaa, 0xd5, 0xee, 0x4c, - 0x12, 0x1a, 0xff, 0x5b, 0x01, 0xf2, 0x15, 0x9c, 0x6f, 0x77, 0xe8, 0x41, 0x68, 0x6f, 0xdf, 0x70, - 0xda, 0xda, 0x5e, 0xb1, 0x8f, 0x50, 0x6b, 0xc7, 0xd1, 0xb4, 0x31, 0x0a, 0x32, 0xdb, 0x2b, 0xee, - 0xf8, 0xdb, 0xaf, 0x23, 0xa1, 0xb2, 0x57, 0xec, 0xfb, 0xdb, 0xaf, 0x27, 0xc9, 0x22, 0x44, 0x62, - 0xc0, 0x18, 0xdf, 0x37, 0xc4, 0x12, 0x83, 0xa3, 0xc3, 0xa5, 0x31, 0xbe, 0xbd, 0x98, 0xa2, 0x84, - 0x9c, 0x85, 0x42, 0xa3, 0x7e, 0x57, 0x6c, 0xf0, 0xa8, 0xf5, 0x0c, 0xba, 0xae, 0xc9, 0x60, 0xac, - 0xce, 0xf5, 0x6a, 0xa5, 0x8e, 0x7a, 0x8e, 0xd1, 0xb8, 0xce, 0x76, 0xcb, 0xee, 0x26, 0x35, 0x1d, - 0x11, 0x22, 0x79, 0x07, 0x26, 0xef, 0x54, 0x57, 0x6f, 0x79, 0x01, 0xdf, 0x9c, 0xc7, 0xe2, 0x69, - 0xbc, 0xdf, 0x6a, 0x5a, 0xf8, 0xb0, 0x91, 0x3c, 0xe5, 0x14, 0x7c, 0x62, 0xc1, 0x69, 0xc6, 0x8a, - 0x0d, 0x89, 0xd3, 0xa4, 0xe2, 0xce, 0x7d, 0x37, 0x7e, 0x46, 0x79, 0xf9, 0xe8, 0x70, 0xe9, 0x05, - 0xfc, 0x82, 0x80, 0xa3, 0x58, 0xf2, 0xb6, 0x9e, 0xe0, 0xda, 0x87, 0x0d, 0xf9, 0x32, 0x9c, 0x4a, - 0x97, 0x34, 0xa2, 0xe7, 0x97, 0x0b, 0x47, 0x87, 0x4b, 0x46, 0x26, 0xff, 0x40, 0x9b, 0xbf, 0xd9, - 0x4c, 0x8c, 0x6f, 0xe6, 0x61, 0x52, 0xd1, 0x62, 0x92, 0xcf, 0x8a, 0x57, 0xf7, 0x9c, 0x76, 0x3f, - 0x53, 0x30, 0x58, 0x29, 0x57, 0x79, 0x75, 0xbc, 0x16, 0x15, 0x6f, 0xf0, 0xb1, 0x7a, 0x29, 0x3f, - 0x8c, 0x7a, 0xe9, 0x0d, 0x00, 0x3e, 0x85, 0xb1, 0x9f, 0x14, 0x61, 0x4f, 0x31, 0xbe, 0x51, 0xa7, - 0x55, 0x8c, 0x4c, 0xee, 0xc3, 0xdc, 0xa6, 0xdf, 0x0b, 0xc2, 0xc6, 0x41, 0x10, 0xd2, 0x0e, 0xe3, - 0x56, 0xf7, 0xbc, 0xb6, 0x58, 0x3e, 0x2f, 0x1e, 0x1d, 0x2e, 0x9d, 0x47, 0x8b, 0x21, 0x2b, 0xc0, - 0x72, 0xfc, 0x00, 0xab, 0xeb, 0x79, 0xaa, 0xd2, 0x29, 0x8b, 0x81, 0x61, 0x42, 0x49, 0x55, 0x59, - 0xb1, 0x73, 0x5f, 0xbc, 0x50, 0x8a, 0x87, 0x08, 0xe5, 0xdc, 0x17, 0x5f, 0x99, 0x7e, 0x31, 0xd5, - 0x49, 0x8c, 0xcf, 0xaa, 0xea, 0xd2, 0x61, 0xf7, 0x25, 0xe3, 0xff, 0x9f, 0x8b, 0x37, 0xf9, 0xfb, - 0x57, 0xc9, 0x5b, 0x30, 0xc6, 0x5f, 0x84, 0xc5, 0xc3, 0xf9, 0xa9, 0x48, 0xe5, 0xa0, 0x3e, 0x17, - 0xf3, 0x77, 0x8a, 0x3f, 0xe0, 0x56, 0x23, 0x9f, 0x32, 0x05, 0x49, 0xf4, 0xc4, 0xa1, 0x6b, 0x3b, - 0x25, 0x77, 0x54, 0xe6, 0x5f, 0xcd, 0x7a, 0xe2, 0x30, 0x7e, 0x67, 0x14, 0xa6, 0x75, 0x34, 0xf5, - 0xd9, 0x38, 0x37, 0xd4, 0xb3, 0xf1, 0x17, 0xa0, 0x28, 0xe6, 0x9b, 0x94, 0x97, 0x5f, 0xc4, 0x87, - 0x1f, 0x01, 0xd3, 0xcc, 0x21, 0x80, 0x0f, 0x87, 0xe9, 0xb5, 0xa9, 0x19, 0x51, 0x91, 0x65, 0xe5, - 0x51, 0xb2, 0x10, 0x8b, 0x90, 0xf2, 0x51, 0x52, 0x5d, 0xce, 0xd1, 0xf3, 0xe4, 0x6b, 0x30, 0xc6, - 0x6e, 0x5f, 0x91, 0x82, 0x0c, 0xbf, 0x92, 0x5d, 0xcc, 0x12, 0x76, 0x4f, 0x1c, 0x89, 0x3c, 0x80, - 0xe2, 0xba, 0x1d, 0x84, 0x0d, 0x4a, 0xdd, 0x21, 0x0c, 0x42, 0x96, 0x44, 0x57, 0xcd, 0xa1, 0xb5, - 0x45, 0x40, 0xa9, 0x9b, 0x78, 0xd1, 0x8f, 0x98, 0x91, 0xaf, 0x00, 0xac, 0x7a, 0x6e, 0xe8, 0x7b, - 0xed, 0x75, 0x6f, 0x77, 0x61, 0x0c, 0x35, 0x13, 0xcf, 0x25, 0x06, 0x20, 0x46, 0xe0, 0xca, 0x89, - 0x48, 0xfd, 0xd6, 0xe4, 0x05, 0x56, 0xdb, 0xdb, 0x55, 0xd7, 0x41, 0x8c, 0x4f, 0x6e, 0x40, 0x59, - 0xaa, 0x7d, 0xb6, 0xba, 0xbb, 0x3e, 0x4e, 0x90, 0xf1, 0x58, 0x2e, 0xa4, 0x8f, 0x43, 0xab, 0x27, - 0xe0, 0xda, 0xb9, 0x99, 0xa0, 0x21, 0x5f, 0x86, 0x33, 0x49, 0x98, 0x1c, 0xe5, 0x62, 0x7c, 0x63, - 0x52, 0xd9, 0x65, 0xcc, 0xfb, 0x7e, 0x2c, 0xc8, 0x4d, 0x98, 0x61, 0x1d, 0xb2, 0x41, 0xed, 0xa0, - 0xc7, 0xad, 0xf6, 0x84, 0xe2, 0x4c, 0xbe, 0x77, 0x8b, 0x55, 0xd8, 0xf6, 0x9a, 0xfb, 0x0a, 0x92, - 0x99, 0xa4, 0x22, 0xd7, 0x61, 0x92, 0x9b, 0x61, 0xf8, 0x35, 0x77, 0xc7, 0x13, 0xaf, 0x22, 0xf2, - 0xb1, 0x40, 0x94, 0xdc, 0x5f, 0x66, 0x65, 0xa6, 0x8a, 0x68, 0x1c, 0xe6, 0xe1, 0x74, 0x76, 0x1d, - 0xe4, 0x2f, 0xc3, 0x29, 0xd1, 0x9f, 0x6d, 0xea, 0x2b, 0x38, 0x43, 0x18, 0xa8, 0xbc, 0x26, 0xc6, - 0xe9, 0xf9, 0x66, 0xc4, 0x20, 0xda, 0x70, 0x18, 0x8b, 0xc4, 0xa4, 0xc8, 0xae, 0x87, 0x7c, 0x0d, - 0x26, 0xd5, 0x6a, 0xf3, 0xc3, 0xdb, 0xfa, 0x0c, 0xa8, 0x4b, 0x65, 0x49, 0x6c, 0x98, 0x31, 0xe9, - 0xd7, 0x7b, 0x34, 0x08, 0xa5, 0xb5, 0x91, 0x90, 0x58, 0xce, 0xa6, 0x6a, 0x91, 0x08, 0x91, 0x56, - 0xaf, 0xec, 0x73, 0x4a, 0x4b, 0xda, 0x84, 0x7e, 0x9b, 0xb1, 0x4f, 0xf2, 0x33, 0xbe, 0x97, 0x87, - 0x33, 0x7d, 0xa6, 0x33, 0xdb, 0xf1, 0x14, 0xc9, 0x10, 0x77, 0xbc, 0x84, 0x40, 0xc8, 0x4d, 0x15, - 0xcf, 0x43, 0x5e, 0x48, 0x60, 0x23, 0x2b, 0xe5, 0xa3, 0xc3, 0xa5, 0x92, 0xb6, 0x52, 0xf3, 0xb5, - 0x2a, 0xb9, 0x0d, 0x23, 0xac, 0x1b, 0x86, 0xb0, 0xb8, 0x91, 0x3a, 0xdd, 0xe9, 0xd0, 0x51, 0x37, - 0x08, 0xec, 0x1b, 0xe4, 0x41, 0x3e, 0x0b, 0x85, 0xcd, 0xcd, 0x75, 0xdc, 0x1d, 0x0a, 0x38, 0xbb, - 0xa7, 0xc2, 0xb0, 0xad, 0x6d, 0x46, 0x53, 0x8c, 0x36, 0xea, 0x11, 0x93, 0xa1, 0x93, 0x0f, 0x12, - 0x96, 0x80, 0xaf, 0x0c, 0x5e, 0xca, 0xc3, 0x1b, 0x06, 0x7e, 0x0c, 0x7b, 0x3c, 0xe3, 0x5b, 0x39, - 0x69, 0xf4, 0x24, 0x26, 0x3f, 0x39, 0x2f, 0xd7, 0x09, 0xea, 0x1d, 0x04, 0x17, 0x15, 0x44, 0x9e, - 0x03, 0xe0, 0x3f, 0xb7, 0xb6, 0x44, 0xa7, 0x97, 0x4c, 0x05, 0x42, 0xde, 0x8c, 0x58, 0x0a, 0x4d, - 0x6d, 0x01, 0x25, 0x81, 0xc4, 0x5a, 0xe3, 0x65, 0xa6, 0x8e, 0x6a, 0xfc, 0x56, 0x3e, 0x3e, 0x35, - 0x6e, 0x38, 0xed, 0x90, 0xfa, 0x64, 0x91, 0x1f, 0x02, 0xf1, 0x65, 0xcd, 0x8c, 0x7e, 0x93, 0x85, - 0xf8, 0x44, 0xe1, 0x4d, 0x8b, 0x8e, 0x8e, 0x57, 0x94, 0xa3, 0xa3, 0x80, 0x47, 0xc7, 0x74, 0xdf, - 0x43, 0xe2, 0x95, 0x8c, 0x9d, 0x10, 0xb7, 0xfe, 0x8c, 0xdd, 0xee, 0x45, 0x98, 0xba, 0xeb, 0xad, - 0x3d, 0x0e, 0x23, 0x44, 0xb6, 0xe5, 0x17, 0x4d, 0x1d, 0xc8, 0x38, 0xde, 0x6b, 0xb7, 0xa8, 0xbf, - 0xb9, 0x67, 0xbb, 0x9a, 0xed, 0x8c, 0x99, 0x82, 0x33, 0xdc, 0xbb, 0xf4, 0x91, 0x8e, 0x3b, 0xce, - 0x71, 0x93, 0xf0, 0xe4, 0xe0, 0x14, 0x53, 0x83, 0x63, 0xfc, 0x70, 0x5e, 0x76, 0xd7, 0xfd, 0xe5, - 0xa7, 0xd4, 0xaa, 0xe2, 0x75, 0xcd, 0xaa, 0x62, 0x2e, 0x7a, 0x0f, 0x8a, 0x4c, 0x92, 0x96, 0xb3, - 0x04, 0x0e, 0xc5, 0x24, 0xe2, 0x97, 0xc7, 0xa0, 0xa4, 0xa2, 0xb3, 0x7e, 0xa8, 0xb4, 0x5a, 0xbe, - 0xda, 0x0f, 0x76, 0xab, 0xe5, 0x9b, 0x08, 0xd5, 0x0c, 0x97, 0x0a, 0x03, 0x0d, 0x97, 0xbe, 0x0a, - 0x13, 0xab, 0x9d, 0x96, 0x66, 0xde, 0x60, 0x64, 0x7c, 0xde, 0xe5, 0x08, 0x89, 0xaf, 0xde, 0xe8, - 0x99, 0xa3, 0xd9, 0x69, 0xa5, 0x8d, 0x1a, 0x62, 0x96, 0x9a, 0xcd, 0xd3, 0xe8, 0xc7, 0xb1, 0x79, - 0xba, 0x0e, 0x13, 0x5b, 0x01, 0xdd, 0xec, 0xb9, 0x2e, 0x6d, 0xe3, 0xc4, 0x2b, 0x72, 0xed, 0x40, - 0x2f, 0xa0, 0x56, 0x88, 0x50, 0xf5, 0x03, 0x22, 0x54, 0x75, 0x80, 0xc7, 0x07, 0x0c, 0xf0, 0x35, - 0x28, 0xd6, 0x29, 0xf5, 0xb1, 0x4f, 0x27, 0xe3, 0x5b, 0x52, 0x97, 0x52, 0xdf, 0x62, 0x1d, 0xab, - 0xd9, 0x42, 0x09, 0x44, 0xcd, 0x80, 0xaa, 0x34, 0xa4, 0x01, 0x15, 0x79, 0x1e, 0x4a, 0xdd, 0xde, - 0x76, 0xdb, 0x69, 0x22, 0x5f, 0x61, 0x79, 0x65, 0x4e, 0x72, 0x18, 0x63, 0x1b, 0x90, 0x0f, 0x60, - 0x0a, 0xb5, 0x22, 0xd1, 0x94, 0x9b, 0xd6, 0x8e, 0x76, 0xad, 0x8c, 0x4b, 0xdf, 0x4d, 0x06, 0xb2, - 0x32, 0xec, 0x0c, 0x75, 0x46, 0xe4, 0x36, 0x8c, 0xef, 0x3a, 0xa1, 0xb5, 0xd7, 0xdb, 0x5e, 0x98, - 0xd1, 0x8c, 0xf4, 0x6e, 0x3a, 0xe1, 0xad, 0xde, 0x36, 0x1f, 0xf2, 0x88, 0x35, 0xee, 0xd1, 0xbb, - 0x4e, 0xb8, 0xd7, 0x53, 0x15, 0x1f, 0x63, 0xbb, 0x88, 0xbb, 0xd8, 0x80, 0x69, 0x7d, 0x56, 0x3c, - 0x01, 0xd3, 0x82, 0xc8, 0xb0, 0xac, 0x58, 0x9e, 0xb8, 0x3d, 0x52, 0x84, 0xf2, 0x24, 0x37, 0x29, - 0x33, 0xa1, 0x1e, 0xf5, 0x8f, 0x49, 0xee, 0xf4, 0xb6, 0xa9, 0xef, 0xd2, 0x90, 0x06, 0xe2, 0x8e, - 0x1e, 0x98, 0x23, 0x95, 0x6e, 0x37, 0x30, 0xfe, 0x61, 0x1e, 0xc6, 0x2b, 0x0f, 0x1a, 0xb8, 0xeb, - 0xbf, 0xaa, 0xbe, 0x0b, 0xab, 0x06, 0x02, 0xd1, 0xbb, 0xb0, 0xfa, 0x1a, 0x7c, 0x25, 0x43, 0x89, - 0x84, 0xae, 0x0f, 0x8a, 0x12, 0x49, 0x53, 0x1d, 0xc5, 0x4f, 0xe4, 0x85, 0x21, 0x9e, 0xc8, 0xa3, - 0x57, 0x8c, 0x91, 0xe3, 0x5f, 0x31, 0xde, 0x82, 0xc9, 0x9a, 0x1b, 0xd2, 0x5d, 0x3f, 0x5e, 0x35, - 0x91, 0x42, 0x2b, 0x02, 0xab, 0x37, 0x6f, 0x05, 0x9b, 0x4d, 0x49, 0xfe, 0x72, 0x12, 0xbd, 0x98, - 0xe0, 0x94, 0xe4, 0x0f, 0x2c, 0x09, 0x6d, 0xa4, 0x44, 0x34, 0xaa, 0x89, 0xf9, 0x26, 0xcd, 0x90, - 0x72, 0xba, 0x4e, 0x8c, 0x77, 0xec, 0xca, 0x6c, 0xb6, 0x19, 0x92, 0xf1, 0xd7, 0x73, 0x30, 0x9f, - 0x35, 0x8d, 0xc8, 0xbb, 0x50, 0xf2, 0xfc, 0x5d, 0xdb, 0x75, 0x7e, 0x90, 0xb7, 0x48, 0x51, 0x99, - 0xab, 0x70, 0x55, 0x27, 0xa6, 0xc2, 0x59, 0x87, 0x28, 0x2d, 0xd7, 0x35, 0x7c, 0x99, 0x1d, 0xa2, - 0x80, 0x8d, 0x1f, 0xcd, 0xc3, 0x64, 0xa5, 0xdb, 0x7d, 0xca, 0x2d, 0x6b, 0x3f, 0xaf, 0x1d, 0x20, - 0x52, 0x03, 0x11, 0xb5, 0xab, 0xbf, 0x5d, 0x9e, 0x72, 0x86, 0xfc, 0x5a, 0x1e, 0x66, 0x12, 0x14, - 0xea, 0xd7, 0xe7, 0x86, 0x34, 0x84, 0xcd, 0x0f, 0x69, 0x08, 0x5b, 0x18, 0xce, 0x10, 0x76, 0xe4, - 0xe3, 0x1c, 0x0a, 0x2f, 0x43, 0xa1, 0xd2, 0xed, 0x26, 0x0d, 0x5c, 0xba, 0xdd, 0xfb, 0xd7, 0xb8, - 0x12, 0xcc, 0xee, 0x76, 0x4d, 0x86, 0xa1, 0xed, 0xd4, 0x63, 0x43, 0xee, 0xd4, 0xc6, 0x6b, 0x30, - 0x81, 0xbc, 0xd0, 0x1c, 0xf4, 0x3c, 0xe0, 0x16, 0x23, 0x2c, 0x41, 0xb5, 0xba, 0xc4, 0xe6, 0xf3, - 0xa7, 0x39, 0x18, 0xc5, 0xdf, 0x4f, 0xe9, 0x1c, 0x5b, 0xd6, 0xe6, 0x58, 0x59, 0x99, 0x63, 0xc3, - 0xcc, 0xae, 0xbf, 0x57, 0x00, 0x58, 0xbd, 0x67, 0x36, 0xb8, 0xae, 0x94, 0xdc, 0x80, 0x19, 0xbb, - 0xdd, 0xf6, 0x1e, 0xd1, 0x96, 0xe5, 0xf9, 0xce, 0xae, 0xe3, 0xf2, 0x9e, 0x93, 0x56, 0x17, 0x7a, - 0x91, 0xfa, 0x16, 0x2b, 0x8a, 0xee, 0xf1, 0x12, 0x95, 0x4f, 0x87, 0x86, 0x7b, 0x5e, 0x4b, 0xaa, - 0x4d, 0x34, 0x3e, 0xa2, 0x28, 0x83, 0xcf, 0x06, 0x2f, 0x51, 0xf9, 0xec, 0xa1, 0x1a, 0x48, 0xca, - 0xd0, 0x1a, 0x1f, 0x51, 0x94, 0xc1, 0x87, 0xeb, 0x8e, 0x02, 0xb2, 0x0e, 0xf8, 0x14, 0xf0, 0xc8, - 0x6a, 0xfa, 0xb4, 0x45, 0xdd, 0xd0, 0xb1, 0xdb, 0x81, 0x50, 0xb4, 0xa1, 0x46, 0x39, 0x55, 0xa8, - 0x2a, 0x1a, 0xb0, 0x70, 0x35, 0x2e, 0x23, 0x97, 0x61, 0xbc, 0x63, 0x3f, 0xb6, 0xec, 0x5d, 0x6e, - 0x7f, 0x34, 0xc5, 0x15, 0x33, 0x02, 0xa4, 0x1e, 0x23, 0x1d, 0xfb, 0x71, 0x65, 0x97, 0xb2, 0x56, - 0xd0, 0xc7, 0x5d, 0x2f, 0x50, 0x5a, 0x31, 0x16, 0xb7, 0x22, 0x51, 0xa4, 0xb6, 0x42, 0x14, 0x89, - 0x56, 0x18, 0xbf, 0x9a, 0x83, 0x67, 0x6a, 0xf8, 0x15, 0xe1, 0xc1, 0x2a, 0x75, 0x43, 0xea, 0xd7, - 0xa9, 0xdf, 0x71, 0xd0, 0x1a, 0xa3, 0x41, 0x43, 0xf2, 0x02, 0x14, 0x2a, 0xe6, 0x5d, 0x31, 0x7f, - 0xf9, 0x7e, 0xaf, 0xd9, 0xc6, 0xb0, 0xd2, 0x48, 0x77, 0x97, 0x3f, 0xe6, 0x4d, 0xa1, 0x02, 0xa5, - 0x4a, 0x10, 0x38, 0xbb, 0x6e, 0x87, 0xbb, 0x23, 0x15, 0x34, 0xeb, 0x1b, 0x01, 0x4f, 0xbd, 0xf5, - 0xa9, 0x24, 0xc6, 0x7f, 0x9d, 0x83, 0xd9, 0x4a, 0xb7, 0xab, 0x7f, 0xb2, 0x6e, 0xf9, 0x95, 0x1b, - 0xde, 0xf2, 0xcb, 0x81, 0x69, 0xad, 0xb9, 0x7c, 0x4a, 0xc5, 0x82, 0xef, 0x80, 0x9e, 0xe1, 0x9f, - 0xdd, 0x8d, 0x40, 0x56, 0xa0, 0x9b, 0x2d, 0x24, 0x18, 0x1b, 0xff, 0x65, 0x11, 0xf7, 0x10, 0xb1, - 0xdb, 0x0a, 0xdb, 0xe4, 0x5c, 0x86, 0x6d, 0xf2, 0x1b, 0xa0, 0x48, 0x38, 0xea, 0x11, 0xa7, 0xc8, - 0x8a, 0xaa, 0xd6, 0x2b, 0x46, 0x26, 0xfb, 0x49, 0x2b, 0xe5, 0x02, 0xb6, 0xe6, 0x85, 0xe4, 0x02, - 0x7e, 0x22, 0x06, 0xca, 0xb7, 0x80, 0xd4, 0x5c, 0x34, 0xa5, 0xa0, 0x8d, 0x7d, 0xa7, 0x7b, 0x9f, - 0xfa, 0xce, 0xce, 0x81, 0x58, 0x00, 0xd8, 0xf9, 0x8e, 0x28, 0xb5, 0x82, 0x7d, 0xa7, 0x6b, 0x3d, - 0xc4, 0x72, 0x33, 0x83, 0x86, 0xbc, 0x07, 0xe3, 0x26, 0x7d, 0xe4, 0x3b, 0xa1, 0xb4, 0xbd, 0x9b, - 0x8e, 0x94, 0xb8, 0x08, 0xe5, 0x6b, 0xc1, 0xe7, 0x3f, 0xd4, 0x5d, 0x51, 0x94, 0x93, 0x65, 0x2e, - 0xa4, 0x70, 0x1b, 0xbb, 0xa9, 0xb8, 0xb5, 0x95, 0x07, 0x8d, 0x7e, 0x32, 0x0a, 0xb9, 0x04, 0xa3, - 0x28, 0xe9, 0x88, 0xbb, 0x00, 0xba, 0xda, 0xa1, 0xec, 0xac, 0x8a, 0x61, 0x88, 0x81, 0x3a, 0x01, - 0x69, 0xab, 0x10, 0x2c, 0x14, 0x51, 0x4a, 0x57, 0x20, 0x49, 0x31, 0x6d, 0xe2, 0x44, 0x62, 0xda, - 0x3a, 0x94, 0x4d, 0xee, 0xb5, 0xdb, 0xaa, 0x74, 0xf1, 0x41, 0x3c, 0x58, 0x00, 0x5c, 0xc9, 0xe7, - 0x8f, 0x0e, 0x97, 0x9e, 0x15, 0x1e, 0xbd, 0x2d, 0xcb, 0xee, 0xf2, 0x77, 0x74, 0x6d, 0x1b, 0x49, - 0x52, 0x92, 0x37, 0x60, 0x84, 0x6d, 0xbd, 0xc2, 0x9e, 0x59, 0xbe, 0xbc, 0xc5, 0xbb, 0x31, 0x5f, - 0x9c, 0x4d, 0x4f, 0xdb, 0x13, 0x90, 0x84, 0x58, 0x30, 0xad, 0x4f, 0x77, 0x61, 0xda, 0xb6, 0x10, - 0xf7, 0xa7, 0x5e, 0x2e, 0x9e, 0xe3, 0x04, 0xcc, 0x6a, 0x22, 0x50, 0x5d, 0x01, 0x89, 0x45, 0xba, - 0x06, 0xc5, 0xcd, 0xd5, 0x7a, 0xdd, 0xf3, 0x43, 0x7e, 0xd5, 0x89, 0x4f, 0x16, 0x06, 0x33, 0x6d, - 0x77, 0x97, 0xf2, 0xb3, 0x38, 0x6c, 0x76, 0xad, 0x2e, 0x43, 0x53, 0xcf, 0x62, 0x49, 0x4a, 0xbe, - 0x02, 0xa7, 0xb6, 0x02, 0x5a, 0x71, 0x0f, 0xf0, 0x74, 0x56, 0x96, 0xca, 0x34, 0x4e, 0x3d, 0x7c, - 0x50, 0x62, 0x57, 0x41, 0xdb, 0x3d, 0xb0, 0xf8, 0xa9, 0x9e, 0xbd, 0x70, 0xb2, 0xb9, 0x90, 0x2b, - 0x50, 0xd8, 0x58, 0xad, 0x8b, 0x3b, 0x91, 0xb4, 0x3c, 0xdd, 0x58, 0xad, 0xf3, 0x89, 0xd4, 0xd1, - 0xcd, 0xe6, 0x37, 0x56, 0xeb, 0x9f, 0x9c, 0x6d, 0xf5, 0x97, 0xf1, 0x4b, 0xc8, 0x02, 0x8c, 0x37, - 0x39, 0x8e, 0xe0, 0x26, 0x7f, 0x12, 0x02, 0x23, 0xb6, 0xbf, 0x2b, 0x8e, 0x41, 0x13, 0xff, 0x26, - 0x2f, 0x43, 0xd9, 0xef, 0xb9, 0x96, 0x1d, 0xf0, 0xa7, 0xb9, 0x5e, 0x40, 0x7d, 0xbe, 0xcd, 0x9a, - 0x53, 0x7e, 0xcf, 0xad, 0x04, 0x4c, 0xee, 0x42, 0x3b, 0xe8, 0x7f, 0x94, 0x03, 0x65, 0xfd, 0x14, - 0x4d, 0xda, 0x72, 0x7c, 0xda, 0x0c, 0xc5, 0xd9, 0x2c, 0xfc, 0x64, 0x39, 0x2c, 0x61, 0xa1, 0x8b, - 0x30, 0xf2, 0x2e, 0x8c, 0x8b, 0x33, 0x44, 0xec, 0x99, 0x72, 0xdd, 0x89, 0x17, 0x17, 0xee, 0x50, - 0x9d, 0x3a, 0x7f, 0x24, 0x11, 0xdb, 0xb2, 0x6f, 0x3f, 0xd8, 0x5c, 0x6d, 0xdb, 0x4e, 0x27, 0x10, - 0x07, 0x01, 0xee, 0x1a, 0x1f, 0x3e, 0x0a, 0xad, 0x26, 0x42, 0xd5, 0x2d, 0x3b, 0x42, 0x35, 0x6e, - 0xca, 0x07, 0x9f, 0x63, 0xcc, 0xcc, 0x97, 0x60, 0xf4, 0x7e, 0xac, 0x16, 0x5c, 0x99, 0x38, 0x3a, - 0x5c, 0xe2, 0x7d, 0x6b, 0x72, 0xb8, 0x41, 0x61, 0x22, 0x9a, 0x77, 0x8c, 0x17, 0xfb, 0x81, 0xbc, - 0xa6, 0x38, 0x2f, 0x36, 0x03, 0x4d, 0x84, 0x32, 0x39, 0x6d, 0xcd, 0x6d, 0x21, 0x42, 0x1e, 0x11, - 0xb0, 0x7b, 0xa8, 0xdb, 0xc2, 0x69, 0xaa, 0xb6, 0x4e, 0xa0, 0x29, 0xd2, 0xd0, 0x8f, 0xe7, 0x60, - 0x5a, 0x1f, 0x63, 0x72, 0x19, 0xc6, 0x84, 0x2b, 0x6c, 0x0e, 0xb5, 0xac, 0x8c, 0xdb, 0x18, 0x77, - 0x82, 0xd5, 0x5c, 0x5f, 0x05, 0x16, 0x13, 0xfa, 0x04, 0x07, 0x21, 0xf1, 0xa0, 0xd0, 0x27, 0x66, - 0x81, 0x29, 0xcb, 0x88, 0xc1, 0xee, 0xa1, 0x41, 0xaf, 0x1d, 0xaa, 0xaf, 0xc3, 0x3e, 0x42, 0x4c, - 0x51, 0x62, 0x7c, 0x27, 0x07, 0x63, 0x7c, 0x63, 0x4c, 0x98, 0xd1, 0xe6, 0x4e, 0x62, 0x46, 0xfb, - 0x0d, 0x98, 0x37, 0xbd, 0x36, 0x0d, 0x2a, 0xee, 0xc1, 0xa3, 0x3d, 0xea, 0xd3, 0xba, 0xef, 0xed, - 0xc8, 0x87, 0xec, 0xc9, 0xe5, 0xe7, 0xb5, 0x0d, 0x38, 0x0b, 0x91, 0xbf, 0x44, 0xfa, 0xac, 0x84, - 0x2d, 0x53, 0x2c, 0x62, 0x6b, 0x35, 0xf1, 0xf0, 0x9d, 0x59, 0x89, 0xf1, 0xf7, 0x73, 0xb0, 0xd8, - 0x9f, 0x35, 0x1e, 0x9f, 0xfc, 0xcf, 0x58, 0x6e, 0xe1, 0xc7, 0x27, 0x87, 0x26, 0x6c, 0x7b, 0x15, - 0x64, 0x62, 0xc2, 0xa9, 0x4a, 0xb3, 0x49, 0xbb, 0x21, 0x63, 0x2c, 0x2c, 0x52, 0x23, 0xb9, 0xa6, - 0xc8, 0xd5, 0x2b, 0x36, 0x22, 0x70, 0x2b, 0x61, 0x69, 0x27, 0x8b, 0xb3, 0x2e, 0x9b, 0xd4, 0xf8, - 0x77, 0x39, 0x80, 0x46, 0xe3, 0xd6, 0x1d, 0x7a, 0x50, 0xb7, 0x1d, 0x14, 0x54, 0xf8, 0x5e, 0x73, - 0x47, 0x6c, 0x0e, 0x25, 0x61, 0xd9, 0xc2, 0xb7, 0xa8, 0x7d, 0x7a, 0xa0, 0x59, 0xb6, 0x48, 0x54, - 0xde, 0x2a, 0xe7, 0xa1, 0x1d, 0x52, 0x46, 0x88, 0x6a, 0x69, 0xd9, 0x2a, 0x84, 0x26, 0x28, 0x15, - 0x64, 0xf2, 0x15, 0x98, 0x8e, 0x7f, 0x45, 0xf6, 0x39, 0xd3, 0xd1, 0x06, 0xa4, 0x17, 0xae, 0x3c, - 0x77, 0x74, 0xb8, 0xb4, 0xa8, 0x70, 0x4d, 0x1a, 0xa9, 0x24, 0x98, 0xbd, 0x39, 0xf2, 0xbf, 0xff, - 0xe2, 0x52, 0x0e, 0x8d, 0xa8, 0x36, 0xd7, 0x1b, 0xb2, 0x99, 0x17, 0x60, 0x24, 0xf2, 0xa6, 0x28, - 0x89, 0x33, 0x47, 0x7f, 0xeb, 0xc6, 0x72, 0x26, 0x5d, 0xc6, 0xed, 0xc1, 0x0d, 0x56, 0x6f, 0x07, - 0x2b, 0x25, 0x37, 0x61, 0x7c, 0xa8, 0x2f, 0xc7, 0x45, 0x99, 0xf1, 0xc5, 0x92, 0x9a, 0x09, 0x5d, - 0xab, 0x26, 0x7f, 0xda, 0x28, 0x71, 0xa1, 0xab, 0xe9, 0xb7, 0x4d, 0x06, 0x33, 0x0e, 0x73, 0x00, - 0xb7, 0x1f, 0x6c, 0x7e, 0xdf, 0x0e, 0x93, 0xf1, 0x93, 0x79, 0x98, 0x61, 0x5d, 0x5e, 0xe9, 0x85, - 0x7b, 0x9e, 0xef, 0x84, 0x07, 0x4f, 0xad, 0x06, 0xfd, 0x6d, 0xed, 0x72, 0xba, 0x28, 0x8f, 0x51, - 0xb5, 0x6d, 0x43, 0x29, 0xd2, 0xff, 0x87, 0x51, 0x98, 0xcb, 0xa0, 0x22, 0xaf, 0x6a, 0xcf, 0x72, - 0x0b, 0x32, 0x6e, 0xc8, 0xf7, 0x0e, 0x97, 0x4a, 0x12, 0x7d, 0x33, 0x8e, 0x23, 0xb2, 0xac, 0xdb, - 0x80, 0xf2, 0x9e, 0xc2, 0x57, 0x3a, 0xd5, 0x06, 0x54, 0xb7, 0xfc, 0xbc, 0x04, 0xa3, 0xb8, 0x75, - 0x09, 0xbb, 0x67, 0x14, 0x3d, 0x71, 0x33, 0xd4, 0x0c, 0xa1, 0x18, 0x80, 0xdc, 0x82, 0x71, 0xf6, - 0xc7, 0x86, 0xdd, 0x15, 0x6f, 0xe4, 0x24, 0x52, 0x8f, 0x20, 0xb4, 0xeb, 0xb8, 0xbb, 0xaa, 0x86, - 0xa4, 0x4d, 0xad, 0x8e, 0xdd, 0xd5, 0x64, 0x64, 0x8e, 0xa8, 0x69, 0x5a, 0x8a, 0xfd, 0x35, 0x2d, - 0xb9, 0x63, 0x35, 0x2d, 0x3b, 0x00, 0x0d, 0x67, 0xd7, 0x75, 0xdc, 0xdd, 0x4a, 0x7b, 0x57, 0x44, - 0x5f, 0xb9, 0xd4, 0x7f, 0x14, 0x2e, 0xc7, 0xc8, 0x38, 0x71, 0x9f, 0x41, 0x43, 0x16, 0x0e, 0xb3, - 0xec, 0xf6, 0xae, 0xe6, 0x6e, 0xa9, 0x70, 0x26, 0x77, 0x01, 0x2a, 0xcd, 0xd0, 0x79, 0xc8, 0xa6, - 0x70, 0x20, 0x04, 0x5a, 0xf9, 0xc9, 0xab, 0x95, 0x3b, 0xf4, 0x00, 0x2f, 0x61, 0xd2, 0x24, 0xc0, - 0x46, 0x54, 0xb6, 0x12, 0x34, 0x5f, 0xba, 0x98, 0x03, 0xe9, 0xc2, 0xa9, 0x4a, 0xab, 0xe5, 0xb0, - 0x36, 0xd8, 0xed, 0x4d, 0x1e, 0x37, 0x07, 0x59, 0x97, 0xb2, 0x59, 0x5f, 0x92, 0xaf, 0xd8, 0x76, - 0x44, 0x65, 0xc9, 0x70, 0x3b, 0x89, 0x6a, 0xb2, 0x19, 0x1b, 0x0d, 0x98, 0xd6, 0x1b, 0xaf, 0x47, - 0x8d, 0x29, 0x41, 0xd1, 0x6c, 0x54, 0xac, 0xc6, 0xad, 0xca, 0xd5, 0x72, 0x8e, 0x94, 0xa1, 0x24, - 0x7e, 0x2d, 0x5b, 0xcb, 0xaf, 0x5f, 0x2f, 0xe7, 0x35, 0xc8, 0xeb, 0x57, 0x97, 0xcb, 0x85, 0xc5, - 0xfc, 0x42, 0x2e, 0xe1, 0x69, 0x3d, 0x5e, 0x2e, 0x72, 0xe5, 0xb8, 0xf1, 0xeb, 0x39, 0x28, 0xca, - 0x6f, 0x27, 0xd7, 0xa1, 0xd0, 0x68, 0xdc, 0x4a, 0xf8, 0x2a, 0xc7, 0xc7, 0x10, 0xdf, 0x6a, 0x83, - 0x40, 0x75, 0x48, 0x61, 0x04, 0x8c, 0x6e, 0x73, 0xbd, 0x21, 0x04, 0x3a, 0x49, 0x17, 0xef, 0xeb, - 0x9c, 0x2e, 0xc3, 0x81, 0xf3, 0x3a, 0x14, 0x6e, 0x3f, 0xd8, 0x14, 0xd7, 0x4d, 0x49, 0x17, 0xef, - 0xa7, 0x9c, 0xee, 0xc3, 0x47, 0xea, 0x01, 0xc0, 0x08, 0x0c, 0x13, 0x26, 0x95, 0x89, 0xcc, 0x25, - 0x98, 0x8e, 0x17, 0x85, 0x4a, 0x11, 0x12, 0x0c, 0x83, 0x98, 0xa2, 0x84, 0xc9, 0x75, 0xeb, 0x5e, - 0xd3, 0x6e, 0x0b, 0x51, 0x08, 0xe5, 0xba, 0x36, 0x03, 0x98, 0x1c, 0x6e, 0xfc, 0x76, 0x0e, 0xca, - 0x75, 0xdf, 0xe3, 0xe1, 0x5c, 0x36, 0xbd, 0x7d, 0xea, 0xde, 0xbf, 0x4a, 0x5e, 0x93, 0x4b, 0x2e, - 0x17, 0xa9, 0xfc, 0x46, 0x71, 0xc9, 0x25, 0xde, 0x4d, 0xc5, 0xb2, 0x53, 0xa2, 0xd1, 0xe4, 0x87, - 0x8f, 0x62, 0x71, 0x4c, 0x34, 0x9a, 0x25, 0x18, 0xc5, 0xcf, 0x11, 0x9b, 0x23, 0x7e, 0x79, 0xc8, - 0x00, 0x26, 0x87, 0x2b, 0x7b, 0xd3, 0x61, 0x3e, 0xd5, 0x86, 0xe5, 0xef, 0xab, 0x48, 0x10, 0x7a, - 0xe3, 0xfa, 0xef, 0xd7, 0xe4, 0x4e, 0x9f, 0x48, 0x10, 0x09, 0x06, 0xdc, 0x91, 0x73, 0x99, 0x3f, - 0xa7, 0x70, 0x77, 0x28, 0x55, 0x69, 0x96, 0x72, 0x2c, 0xff, 0x22, 0xcc, 0x27, 0xfb, 0x17, 0x75, - 0xbb, 0x15, 0x98, 0xd1, 0xe1, 0x52, 0xcd, 0x7b, 0x26, 0xb3, 0xde, 0xfb, 0xcb, 0x66, 0x12, 0xdf, - 0xf8, 0xb7, 0x39, 0x98, 0xc0, 0x3f, 0xcd, 0x1e, 0x17, 0x47, 0x2b, 0x0f, 0x1a, 0x42, 0xe3, 0xa4, - 0x8a, 0xa3, 0xf6, 0xa3, 0x40, 0x9a, 0x22, 0x6a, 0x1b, 0x56, 0x84, 0x2c, 0x48, 0xf9, 0xb3, 0x91, - 0xd4, 0x75, 0x46, 0xa4, 0xfc, 0x7d, 0x29, 0x48, 0x90, 0x0a, 0x64, 0xf4, 0x2d, 0xe0, 0xf2, 0xb1, - 0x6a, 0x18, 0x86, 0x74, 0x5e, 0x5b, 0xf7, 0x2d, 0xe0, 0x68, 0x68, 0x17, 0xf6, 0xa0, 0xc1, 0x44, - 0x66, 0xd5, 0x2e, 0x8c, 0x7d, 0xa3, 0x26, 0x2e, 0x0b, 0x24, 0xe3, 0x9f, 0x4c, 0x25, 0x3b, 0x50, - 0x9c, 0x9e, 0x27, 0x5c, 0x68, 0x6f, 0xc1, 0x68, 0xa5, 0xdd, 0xf6, 0x1e, 0x89, 0x2d, 0x47, 0x2a, - 0x04, 0xa2, 0xfe, 0xe3, 0x87, 0x23, 0x6a, 0x4b, 0x35, 0x9f, 0x73, 0x06, 0x20, 0xab, 0x30, 0x51, - 0x79, 0xd0, 0xa8, 0xd5, 0xaa, 0x9b, 0x9b, 0xdc, 0xbf, 0xb6, 0xb0, 0xf2, 0x92, 0xec, 0x1f, 0xc7, - 0x69, 0x59, 0x49, 0xc3, 0x95, 0xf8, 0x66, 0x15, 0xd3, 0x91, 0x77, 0x00, 0x6e, 0x7b, 0x8e, 0xcb, - 0xb5, 0xc3, 0xa2, 0xf1, 0xe7, 0x8e, 0x0e, 0x97, 0x26, 0x3f, 0xf4, 0x1c, 0x57, 0xa8, 0x93, 0xd9, - 0xb7, 0xc7, 0x48, 0xa6, 0xf2, 0x37, 0xeb, 0xe9, 0x15, 0x8f, 0x1b, 0xb4, 0x8e, 0xc6, 0x3d, 0xbd, - 0xed, 0xa5, 0xd4, 0x98, 0x12, 0x8d, 0x74, 0x60, 0xa6, 0xd1, 0xdb, 0xdd, 0xa5, 0xec, 0x98, 0x10, - 0x6a, 0xba, 0x31, 0xa1, 0x11, 0x88, 0x82, 0xb1, 0xf1, 0x9b, 0x22, 0xbb, 0xa6, 0x06, 0x2b, 0xaf, - 0xb2, 0x55, 0xf1, 0xdd, 0xc3, 0x25, 0x61, 0x10, 0xc3, 0xe4, 0xbe, 0x40, 0xd2, 0xa7, 0x95, 0x74, - 0x49, 0xde, 0xe4, 0x1e, 0x8c, 0xf1, 0xa7, 0x38, 0xe1, 0x2f, 0xfa, 0xfc, 0x80, 0x15, 0xc8, 0x11, - 0xfb, 0x3d, 0xf6, 0xf2, 0x52, 0xf2, 0x00, 0x8a, 0xab, 0x8e, 0xdf, 0x6c, 0xd3, 0xd5, 0x9a, 0x10, - 0x24, 0x5e, 0x18, 0xc0, 0x52, 0xa2, 0xf2, 0x7e, 0x69, 0xe2, 0xaf, 0xa6, 0xa3, 0x0a, 0x16, 0x12, - 0x83, 0xfc, 0xf5, 0x1c, 0x3c, 0x13, 0x7d, 0x7d, 0x65, 0x97, 0xba, 0xe1, 0x86, 0x1d, 0x36, 0xf7, - 0xa8, 0x2f, 0x7a, 0x69, 0x62, 0x50, 0x2f, 0xbd, 0x99, 0xea, 0xa5, 0x8b, 0x71, 0x2f, 0xd9, 0x8c, - 0x99, 0xd5, 0xe1, 0xdc, 0xd2, 0x7d, 0x36, 0xa8, 0x56, 0x62, 0x01, 0xc4, 0x8f, 0xcc, 0xc2, 0xb2, - 0xee, 0xa5, 0x01, 0x0d, 0x8e, 0x91, 0x85, 0x9f, 0x60, 0xf4, 0x5b, 0xb3, 0x04, 0x8f, 0xa0, 0xe4, - 0x8e, 0x74, 0xce, 0xe6, 0x22, 0xce, 0xf9, 0x01, 0xbc, 0xb9, 0xc3, 0xf6, 0xdc, 0x80, 0x30, 0x0c, - 0x7c, 0xb4, 0xd7, 0xed, 0x6d, 0x21, 0xd5, 0x1c, 0x33, 0xda, 0xeb, 0x76, 0x3c, 0xda, 0x6d, 0x3b, - 0x39, 0xda, 0xeb, 0xf6, 0x36, 0x59, 0xe5, 0x11, 0x25, 0x78, 0xf8, 0x81, 0xe7, 0x06, 0x71, 0x93, - 0x2a, 0xb2, 0x8c, 0xc8, 0x12, 0x5f, 0x82, 0x89, 0x46, 0xd7, 0x6e, 0xd2, 0xb6, 0xb3, 0x13, 0x0a, - 0x0b, 0x86, 0x17, 0x07, 0xb0, 0x8a, 0x70, 0xc5, 0x8b, 0xb5, 0xfc, 0xa9, 0xde, 0xb9, 0x22, 0x1c, - 0xf6, 0x85, 0x9b, 0xf5, 0x0d, 0xa1, 0xb0, 0x1b, 0xf4, 0x85, 0x9b, 0xf5, 0x0d, 0x21, 0xc0, 0x74, - 0x3b, 0x9a, 0x00, 0x53, 0xdf, 0x20, 0x5d, 0x98, 0xde, 0xa4, 0xbe, 0x6f, 0xef, 0x78, 0x7e, 0x87, - 0xab, 0x85, 0xb9, 0x4b, 0xeb, 0xa5, 0x41, 0xfc, 0x34, 0x02, 0xae, 0x0d, 0x0d, 0x25, 0xcc, 0x4a, - 0xea, 0x92, 0x13, 0xfc, 0x59, 0x9f, 0xac, 0x38, 0xe1, 0x76, 0xaf, 0xb9, 0x4f, 0xc3, 0x85, 0xd9, - 0x63, 0xfb, 0x24, 0xc2, 0xe5, 0x7d, 0xb2, 0x2d, 0x7f, 0xaa, 0x7d, 0x12, 0xe1, 0xb0, 0x69, 0x20, - 0xe2, 0x46, 0x90, 0x63, 0xa7, 0x01, 0x47, 0xe4, 0xd3, 0xa0, 0x5f, 0x00, 0x09, 0xb2, 0x07, 0xa5, - 0x15, 0xaf, 0xe7, 0x32, 0xb9, 0xb6, 0x6b, 0x3b, 0xfe, 0xc2, 0x1c, 0xb2, 0x7d, 0x79, 0xd0, 0x07, - 0x2b, 0xe8, 0xdc, 0x5f, 0x60, 0x9b, 0x41, 0x98, 0xe8, 0xcc, 0x40, 0xea, 0x03, 0x8f, 0x8a, 0x4a, - 0x5a, 0x30, 0x89, 0x53, 0xb9, 0x4a, 0x1f, 0x7a, 0xdd, 0x60, 0x61, 0x1e, 0x2b, 0xba, 0x70, 0xdc, - 0xa2, 0xe0, 0xd8, 0xdc, 0x92, 0x00, 0x97, 0x86, 0xd5, 0x42, 0x88, 0xaa, 0x75, 0x57, 0x10, 0x8d, - 0x7f, 0x38, 0x0a, 0x4b, 0xc7, 0x30, 0x23, 0xf7, 0xe5, 0xd9, 0xc4, 0x25, 0x80, 0x4f, 0x0f, 0xf7, - 0x0d, 0x97, 0x8f, 0x3d, 0xb6, 0xde, 0x82, 0xe9, 0x7b, 0x8a, 0x51, 0x43, 0x64, 0x64, 0x82, 0x34, - 0xaa, 0xb9, 0x83, 0xe5, 0xb4, 0xcc, 0x04, 0xea, 0xe2, 0x9f, 0x16, 0x60, 0x04, 0x05, 0x8b, 0x17, - 0xa0, 0xd0, 0xe8, 0x6d, 0xab, 0x0f, 0x73, 0x81, 0xb6, 0x5d, 0xb3, 0x52, 0xf2, 0x36, 0x4c, 0x0a, - 0xef, 0x28, 0xe5, 0x76, 0x8a, 0x9d, 0x24, 0x5d, 0xa9, 0x92, 0xbe, 0x1b, 0x0a, 0x3a, 0x79, 0x0f, - 0x4a, 0x75, 0xa7, 0x4b, 0xdb, 0x8e, 0x4b, 0x15, 0x4f, 0x04, 0x1c, 0xcb, 0xae, 0x80, 0xa7, 0x1e, - 0xeb, 0x54, 0x02, 0xdd, 0x8f, 0x6b, 0x64, 0x78, 0x3f, 0xae, 0xf7, 0xa0, 0x54, 0xa5, 0x3b, 0x8e, - 0xeb, 0x88, 0xfe, 0x19, 0x8d, 0x2b, 0x6e, 0x45, 0x70, 0x9d, 0x5a, 0x23, 0x20, 0x2b, 0x30, 0x65, - 0xd2, 0xae, 0x17, 0x38, 0xa1, 0xe7, 0x1f, 0x6c, 0x99, 0x35, 0x61, 0x00, 0x83, 0x1a, 0x3c, 0x3f, - 0x2a, 0xb0, 0x7a, 0xbe, 0x7a, 0x12, 0xe9, 0x24, 0xe4, 0x2e, 0xcc, 0xc6, 0x00, 0xdd, 0x70, 0x4c, - 0xbc, 0xcc, 0x44, 0x7c, 0xd2, 0x26, 0xdf, 0x69, 0x52, 0xfd, 0x9b, 0x4c, 0xba, 0x23, 0x0c, 0xc8, - 0x93, 0xdf, 0xe4, 0xd3, 0x9d, 0xec, 0x6f, 0x32, 0xe9, 0x8e, 0xf1, 0x9b, 0x05, 0x38, 0xd3, 0x67, - 0x6b, 0x23, 0x77, 0xf5, 0xe9, 0xfa, 0xc2, 0xe0, 0x9d, 0xf0, 0xf8, 0x69, 0xba, 0x0e, 0xe5, 0xb5, - 0x3b, 0x78, 0xa1, 0xe7, 0xef, 0xde, 0xab, 0x15, 0x29, 0x84, 0x62, 0xf3, 0xe9, 0x3e, 0x3a, 0x8f, - 0xc8, 0xf7, 0xf2, 0xa6, 0x16, 0xc3, 0x26, 0x45, 0xb9, 0xf8, 0xc3, 0x79, 0x31, 0x6f, 0x13, 0x01, - 0x47, 0x73, 0x27, 0x0a, 0x38, 0xfa, 0x05, 0x28, 0xad, 0xdd, 0xe1, 0xea, 0xb6, 0x5b, 0x76, 0xb0, - 0x27, 0xe6, 0x14, 0x76, 0x21, 0xdd, 0x97, 0xef, 0x3c, 0x7b, 0xb6, 0x76, 0xb1, 0xd5, 0x28, 0xc8, - 0x16, 0xcc, 0xf1, 0x6f, 0x73, 0x76, 0x9c, 0x26, 0x8f, 0x5b, 0xe8, 0xd8, 0x6d, 0x31, 0xc3, 0x5e, - 0x38, 0x3a, 0x5c, 0x5a, 0xa2, 0xfb, 0xe8, 0x16, 0x23, 0xca, 0xad, 0x00, 0x11, 0x54, 0xff, 0x98, - 0x0c, 0x7a, 0x35, 0x0a, 0x9a, 0x39, 0x81, 0x15, 0xb2, 0xda, 0x58, 0xdd, 0x0c, 0x97, 0x23, 0x19, - 0x7f, 0x32, 0x0a, 0x8b, 0xfd, 0xc5, 0x2e, 0xf2, 0xbe, 0x3e, 0x80, 0x17, 0x8e, 0x15, 0xd4, 0x8e, - 0x1f, 0xc3, 0x0f, 0x60, 0x7e, 0xcd, 0x0d, 0xa9, 0xdf, 0xf5, 0x1d, 0x19, 0x3d, 0xed, 0x96, 0x17, - 0x48, 0x37, 0x24, 0xd4, 0xc2, 0xd3, 0xa8, 0x5c, 0x38, 0xd4, 0xe1, 0xc3, 0x91, 0xaa, 0x85, 0xcf, - 0xe2, 0x40, 0xd6, 0x60, 0x5a, 0x81, 0xb7, 0x7b, 0xbb, 0xea, 0x63, 0xbe, 0xca, 0xb3, 0xdd, 0x53, - 0x7d, 0x34, 0x12, 0x44, 0xe8, 0xea, 0x14, 0xda, 0xa1, 0xd3, 0xbc, 0xfd, 0xe0, 0x4e, 0x43, 0x0c, - 0x27, 0x77, 0x75, 0x42, 0xa8, 0xf5, 0xe1, 0xa3, 0x7d, 0x4d, 0x6e, 0x8a, 0x91, 0x17, 0x7f, 0xe9, - 0x44, 0x3b, 0xe1, 0xe7, 0x01, 0xe2, 0xa5, 0xa4, 0x46, 0x42, 0x88, 0x97, 0x9e, 0xee, 0xcd, 0x28, - 0xa1, 0xe4, 0x16, 0xcc, 0xc4, 0xbf, 0xee, 0x3d, 0x72, 0xe5, 0x83, 0x1a, 0x57, 0xc1, 0x2a, 0x2b, - 0xd7, 0x63, 0x65, 0xaa, 0x28, 0x9e, 0x20, 0x23, 0xcb, 0x50, 0x7c, 0xe0, 0xf9, 0xfb, 0x3b, 0x6c, - 0x8c, 0x47, 0xe2, 0xcb, 0xc2, 0x23, 0x01, 0x53, 0x85, 0x62, 0x89, 0xc7, 0x96, 0xcb, 0x9a, 0xfb, - 0xd0, 0xf1, 0x3d, 0x34, 0x80, 0x50, 0x4d, 0x00, 0x69, 0x0c, 0xd6, 0x62, 0xd0, 0xc4, 0x60, 0x72, - 0x09, 0x46, 0x2b, 0xcd, 0xd0, 0xf3, 0xc5, 0xf6, 0xc7, 0x67, 0x0a, 0x03, 0x68, 0x33, 0x85, 0x01, - 0x58, 0x27, 0xb2, 0x3d, 0x69, 0x3c, 0xee, 0x44, 0x7d, 0x23, 0x62, 0xa5, 0xec, 0xb2, 0x63, 0xd2, - 0x1d, 0xd4, 0x8e, 0x6a, 0xe1, 0x74, 0x77, 0x52, 0x2a, 0x77, 0x81, 0x66, 0xfc, 0x55, 0xe8, 0x3b, - 0xe5, 0x99, 0x74, 0x79, 0xb2, 0x29, 0xbf, 0x6e, 0x0f, 0x31, 0xe5, 0x5f, 0x8d, 0x7c, 0x24, 0xd5, - 0xa8, 0x52, 0x08, 0x51, 0xe5, 0x1a, 0xe1, 0x2d, 0xa9, 0xcf, 0xbf, 0xc2, 0x49, 0xe6, 0xdf, 0xdf, - 0x2d, 0x9e, 0x64, 0xfe, 0x89, 0xfe, 0xcd, 0x0f, 0xdb, 0xbf, 0x85, 0xa1, 0xfa, 0x97, 0x1d, 0x2a, - 0x51, 0x2c, 0xe7, 0xba, 0x1d, 0x6a, 0x3b, 0x62, 0x14, 0x80, 0xdb, 0xea, 0xda, 0x5a, 0xbc, 0x43, - 0x9d, 0x44, 0x11, 0x12, 0x90, 0xc3, 0x68, 0x5a, 0x48, 0x48, 0xd0, 0xab, 0xe8, 0x6c, 0x23, 0x90, - 0x67, 0x7e, 0x03, 0x3d, 0xee, 0xc4, 0x64, 0xe3, 0xe6, 0x31, 0x52, 0x4c, 0xe0, 0xce, 0x78, 0xda, - 0xfb, 0x84, 0x46, 0x94, 0x9c, 0xe7, 0xe3, 0x27, 0x9a, 0xe7, 0xdc, 0x22, 0xdc, 0x5f, 0xf7, 0x76, - 0x1d, 0xe9, 0x97, 0x25, 0x2d, 0xc2, 0x7d, 0xab, 0xcd, 0xa0, 0x09, 0x8b, 0x70, 0x8e, 0x4a, 0x5e, - 0x83, 0x31, 0xf6, 0xa3, 0x56, 0x15, 0x36, 0x1b, 0xa8, 0xf4, 0x40, 0x22, 0xdd, 0x19, 0x8e, 0x23, - 0xc9, 0x6a, 0xd6, 0x3a, 0xb6, 0xd3, 0x16, 0x71, 0x87, 0xe2, 0x6a, 0x28, 0x83, 0x26, 0xab, 0x41, - 0x54, 0xd2, 0x84, 0x92, 0x49, 0x77, 0xea, 0xbe, 0x17, 0xd2, 0x66, 0x48, 0x5b, 0xe2, 0xa2, 0x27, - 0x75, 0x1d, 0x2b, 0x9e, 0xc7, 0x2f, 0xb1, 0xe8, 0x37, 0x95, 0xfb, 0xee, 0xe1, 0x12, 0x30, 0x10, - 0xf7, 0xb4, 0x64, 0x22, 0x0f, 0x1b, 0xff, 0xae, 0x24, 0x56, 0x0f, 0x36, 0x95, 0x29, 0xf9, 0x06, - 0xdb, 0xea, 0xa3, 0x2e, 0x89, 0x2b, 0x2b, 0xf5, 0xa9, 0xec, 0xf5, 0xcc, 0xca, 0x96, 0x94, 0xde, - 0xce, 0xac, 0x34, 0xb3, 0x12, 0xf2, 0x0e, 0x4c, 0xae, 0xd6, 0x56, 0x3d, 0x77, 0xc7, 0xd9, 0x6d, - 0xdc, 0xaa, 0xe0, 0x6d, 0x51, 0xc8, 0x6b, 0x4d, 0xc7, 0x6a, 0x22, 0xdc, 0x0a, 0xf6, 0x6c, 0x2d, - 0x14, 0x46, 0x8c, 0x4f, 0x6e, 0xc2, 0xb4, 0xfc, 0x69, 0xd2, 0x1d, 0x26, 0xaf, 0x4d, 0x2b, 0x9e, - 0xd9, 0x11, 0x07, 0xd6, 0x11, 0xba, 0xc8, 0x96, 0x20, 0x63, 0x93, 0xb1, 0x4a, 0xbb, 0x6d, 0xef, - 0x80, 0x7d, 0xde, 0xa6, 0x43, 0x7d, 0xbc, 0x16, 0x8a, 0xc9, 0xd8, 0x8a, 0x4a, 0xac, 0xd0, 0xd1, - 0x2d, 0x55, 0x74, 0x22, 0x26, 0xfa, 0x89, 0x29, 0x7e, 0xdf, 0x09, 0x9c, 0x6d, 0xa7, 0xed, 0x84, - 0x07, 0x78, 0x21, 0x14, 0xb2, 0x8f, 0x5c, 0x17, 0x0f, 0xa3, 0x52, 0x55, 0xf4, 0x4b, 0x91, 0x1a, - 0xbf, 0x9e, 0x87, 0x67, 0x07, 0x29, 0x47, 0x48, 0x43, 0xdf, 0x07, 0x2f, 0x0e, 0xa1, 0x50, 0x39, - 0x7e, 0x27, 0x5c, 0xeb, 0x73, 0xcf, 0xc0, 0xce, 0x48, 0xdc, 0x33, 0xd4, 0xce, 0x48, 0xdc, 0x38, - 0x1e, 0x8a, 0x6d, 0xee, 0xa3, 0x06, 0x65, 0xb8, 0x0e, 0x13, 0xab, 0x9e, 0x1b, 0xd2, 0xc7, 0x61, - 0x22, 0x04, 0x11, 0x07, 0x26, 0x03, 0x52, 0x48, 0x54, 0xe3, 0x5f, 0x15, 0xe0, 0xdc, 0x40, 0xed, - 0x00, 0xd9, 0xd4, 0x7b, 0xed, 0xd2, 0x30, 0x2a, 0x85, 0xe3, 0xbb, 0x6d, 0x39, 0x65, 0xe1, 0x7c, - 0xbc, 0x57, 0xad, 0x09, 0x84, 0x47, 0x5a, 0xb9, 0xd9, 0xf6, 0xb6, 0x51, 0x7f, 0xe4, 0xb8, 0xbb, - 0x22, 0x42, 0x0b, 0xf7, 0x10, 0xc5, 0x52, 0x6b, 0xb7, 0xed, 0x6d, 0x73, 0x3d, 0x94, 0xe3, 0xaa, - 0x62, 0x51, 0x06, 0xf5, 0xe2, 0xbf, 0xca, 0x89, 0x8e, 0xff, 0x0c, 0x8c, 0xe3, 0xe7, 0x47, 0xdd, - 0xce, 0x35, 0xfb, 0xb8, 0xb3, 0x3b, 0xba, 0x66, 0x9f, 0xa3, 0x91, 0x6b, 0x50, 0x5c, 0xb5, 0xdb, - 0x6d, 0x25, 0xe8, 0x13, 0x2a, 0x0d, 0x9a, 0x08, 0x4b, 0x98, 0xfe, 0x4b, 0x44, 0x76, 0x14, 0xf2, - 0xbf, 0x95, 0xf3, 0x07, 0x37, 0x60, 0x41, 0x96, 0x38, 0x82, 0x14, 0x64, 0x8c, 0x70, 0xdf, 0xf4, - 0xa2, 0xb0, 0x32, 0x3c, 0xc2, 0x3d, 0x03, 0x68, 0x11, 0xee, 0x19, 0xc0, 0xf8, 0xe5, 0x51, 0x78, - 0x6e, 0xb0, 0xda, 0x8c, 0x6c, 0xe9, 0xc3, 0xfa, 0xca, 0x50, 0xca, 0xb6, 0xe3, 0xc7, 0x55, 0xe6, - 0x8b, 0xe0, 0x1d, 0x72, 0x31, 0xed, 0x6e, 0xf9, 0xbd, 0xc3, 0x25, 0xc5, 0x9f, 0xe4, 0xb6, 0xe7, - 0xb8, 0xca, 0x3b, 0xef, 0xd7, 0x53, 0x82, 0xc2, 0xe4, 0xf2, 0xf5, 0xe1, 0xbe, 0x2c, 0xa6, 0xe3, - 0x7b, 0xd5, 0x90, 0x02, 0x06, 0xf9, 0x00, 0x46, 0xee, 0xd5, 0xaa, 0xab, 0xe2, 0xd1, 0xe5, 0x33, - 0xc3, 0x55, 0xc6, 0x28, 0x44, 0x35, 0x68, 0x76, 0xe1, 0x39, 0xad, 0xa6, 0x6a, 0x76, 0xc1, 0xca, - 0x17, 0xdf, 0x84, 0x72, 0xf2, 0xa3, 0xc8, 0x05, 0x18, 0xc1, 0xa6, 0x29, 0xde, 0xa8, 0x89, 0x6f, - 0xc3, 0xf2, 0xc5, 0x9f, 0xcd, 0x01, 0xc4, 0x95, 0x30, 0x71, 0xab, 0x16, 0x04, 0xbd, 0x28, 0xf2, - 0x26, 0x8a, 0x5b, 0x0e, 0x42, 0xd4, 0x13, 0x94, 0xe3, 0x90, 0x0f, 0xd0, 0x1b, 0x16, 0xed, 0x3f, - 0x71, 0x50, 0x6e, 0x6d, 0x6e, 0xd6, 0x05, 0x39, 0xb7, 0xb1, 0x41, 0x99, 0x3a, 0x32, 0x1c, 0xe5, - 0x26, 0xd4, 0x7b, 0x61, 0xd8, 0xb5, 0x38, 0x4b, 0xb3, 0x1f, 0xf9, 0xe2, 0x86, 0x58, 0x2c, 0x18, - 0xf8, 0x4b, 0x8d, 0xe2, 0x20, 0xbe, 0x4b, 0x04, 0xfe, 0xd2, 0x42, 0x40, 0xe8, 0x81, 0xbf, 0x54, - 0x22, 0xe3, 0x3f, 0xe4, 0xe0, 0x6c, 0x5f, 0x45, 0x0f, 0xa9, 0xeb, 0x33, 0xf4, 0xa5, 0xe3, 0x34, - 0x43, 0xc7, 0x4e, 0xce, 0xc5, 0x6f, 0xc9, 0xc5, 0xfe, 0x2e, 0x94, 0x1a, 0xbd, 0xed, 0xe4, 0xfd, - 0x98, 0x87, 0xe5, 0x53, 0xe0, 0xaa, 0x18, 0xa0, 0xe2, 0xb3, 0xf6, 0xcb, 0xd0, 0x07, 0xc2, 0x5e, - 0x55, 0x31, 0x92, 0x8f, 0x42, 0xb7, 0xa4, 0x03, 0x9f, 0xe9, 0x44, 0xc6, 0xaf, 0xe5, 0xb3, 0x15, - 0x0d, 0x37, 0x57, 0xeb, 0x27, 0x51, 0x34, 0xdc, 0x5c, 0xad, 0x1f, 0xdf, 0xf6, 0xff, 0x4e, 0xb6, - 0x9d, 0x9b, 0x6e, 0xf1, 0x63, 0x43, 0x3e, 0x20, 0x49, 0xd3, 0x2d, 0x71, 0xc4, 0x04, 0x09, 0xd3, - 0x2d, 0x81, 0x4c, 0x5e, 0x87, 0x89, 0x75, 0x8f, 0xc7, 0x24, 0x93, 0x2d, 0xe6, 0xb1, 0x4d, 0x24, - 0x50, 0x3d, 0x63, 0x22, 0x4c, 0x76, 0xb7, 0xd3, 0x07, 0x5e, 0xfa, 0x02, 0xe0, 0x3c, 0x4c, 0x4c, - 0x17, 0xfd, 0x99, 0x45, 0x27, 0x33, 0xfe, 0xc1, 0x28, 0x18, 0xc7, 0x2b, 0x89, 0xc9, 0x17, 0xf5, - 0xbe, 0xbb, 0x3c, 0xb4, 0x7a, 0x79, 0xa8, 0x73, 0xab, 0xd2, 0x6b, 0x39, 0xd4, 0x6d, 0xea, 0x01, - 0xc5, 0x04, 0x4c, 0xdd, 0xf3, 0x25, 0xde, 0x47, 0x89, 0x20, 0xb1, 0xf8, 0xcf, 0x0b, 0xf1, 0x52, - 0x4b, 0xc8, 0x17, 0xb9, 0x8f, 0x20, 0x5f, 0x90, 0x3b, 0x50, 0x56, 0x21, 0x8a, 0xa2, 0x12, 0xc5, - 0x3f, 0x8d, 0x51, 0xe2, 0xa3, 0x52, 0x84, 0xba, 0x90, 0x52, 0x18, 0x5e, 0x48, 0x49, 0x28, 0x4a, - 0x47, 0x4e, 0xa6, 0x28, 0x15, 0x01, 0xc8, 0x02, 0x71, 0x4a, 0x8f, 0xea, 0x01, 0xc8, 0x32, 0x4e, - 0x6a, 0x15, 0x5d, 0xc6, 0x50, 0xc3, 0x9f, 0x4a, 0x8c, 0x9d, 0x28, 0x86, 0x1a, 0xa7, 0xcf, 0x8a, - 0xa1, 0x16, 0x91, 0xb0, 0x13, 0xdf, 0xec, 0xb9, 0x3c, 0x77, 0xcc, 0x78, 0x7c, 0xe2, 0xfb, 0x3d, - 0xd7, 0x4a, 0xe6, 0x8f, 0x89, 0x10, 0x8d, 0x7f, 0x3c, 0x92, 0x2d, 0x61, 0xc5, 0xef, 0x08, 0x27, - 0x90, 0xb0, 0x22, 0xa2, 0x4f, 0x66, 0xa6, 0x6e, 0xc1, 0x9c, 0x34, 0x27, 0xc7, 0xda, 0x5b, 0xd4, - 0xdf, 0x32, 0xd7, 0xc5, 0x10, 0xa3, 0xde, 0x2e, 0x32, 0x44, 0xef, 0x8a, 0x72, 0xab, 0xe7, 0x6b, - 0x7a, 0xbb, 0x0c, 0xfa, 0xc5, 0x7f, 0x24, 0xd5, 0x92, 0xea, 0x20, 0xa0, 0xeb, 0x7f, 0x2e, 0x6b, - 0x10, 0x7a, 0x3d, 0x6d, 0x18, 0x75, 0x12, 0xbe, 0xf7, 0x46, 0x2a, 0xe4, 0x2d, 0x5d, 0xe0, 0x56, - 0xd5, 0xce, 0x3a, 0x97, 0x04, 0x11, 0xd9, 0x85, 0xb3, 0xf1, 0x7d, 0x44, 0xb9, 0x6e, 0x21, 0x47, - 0xde, 0xe0, 0x4b, 0x47, 0x87, 0x4b, 0x2f, 0x29, 0xf7, 0x19, 0xf5, 0xd6, 0x96, 0xe0, 0xde, 0x9f, - 0x17, 0xdb, 0x6f, 0x57, 0x7c, 0xdb, 0x6d, 0xee, 0x29, 0x73, 0x1e, 0xf7, 0xdb, 0x6d, 0x84, 0xa6, - 0xe2, 0x0c, 0xc5, 0xc8, 0xc6, 0xdf, 0xc9, 0x67, 0xeb, 0x75, 0xc4, 0x73, 0xd1, 0x09, 0xf4, 0x3a, - 0x9c, 0xe2, 0xf8, 0x53, 0xe2, 0x1f, 0xc8, 0x53, 0xe2, 0x25, 0x18, 0xdf, 0xa4, 0xae, 0xed, 0x46, - 0xf1, 0xbb, 0xd0, 0x6c, 0x25, 0xe4, 0x20, 0x53, 0x96, 0x91, 0xf7, 0x81, 0xd4, 0x6d, 0x9f, 0xba, - 0xe1, 0xaa, 0xd7, 0xe9, 0xda, 0x7e, 0xd8, 0xc1, 0xec, 0x3a, 0xfc, 0x68, 0x78, 0xfe, 0xe8, 0x70, - 0xe9, 0x5c, 0x17, 0x4b, 0xad, 0xa6, 0x52, 0xac, 0x4a, 0xe4, 0x69, 0x62, 0x72, 0x05, 0xc6, 0xa5, - 0x35, 0x46, 0x21, 0x8e, 0x58, 0x9a, 0xb6, 0xc4, 0x90, 0x58, 0xc6, 0x3f, 0x1f, 0x85, 0xf3, 0xc7, - 0xbd, 0x8d, 0x91, 0x1d, 0x80, 0x7b, 0xee, 0xb6, 0x67, 0xfb, 0x2d, 0x76, 0x67, 0xc8, 0x1d, 0x2b, - 0x59, 0xaa, 0xc4, 0x97, 0x63, 0x4a, 0x56, 0xc8, 0xdd, 0x9a, 0xbd, 0x08, 0x66, 0x2a, 0x9c, 0xc9, - 0x57, 0xa1, 0x68, 0xd2, 0xa6, 0xf7, 0x90, 0x0a, 0xfd, 0xe7, 0xe4, 0xf2, 0x67, 0x87, 0xad, 0x45, - 0xd2, 0x61, 0x1d, 0xe8, 0xef, 0xe9, 0x0b, 0x88, 0x19, 0xf1, 0x24, 0x5f, 0x83, 0x49, 0x9e, 0x44, - 0xa9, 0xb2, 0x13, 0x0a, 0x1d, 0xe9, 0xf1, 0xf1, 0x5a, 0x72, 0x6c, 0x93, 0xe4, 0x69, 0x99, 0x2c, - 0x7b, 0x47, 0xf3, 0x1f, 0xe1, 0xf1, 0x5a, 0x14, 0x96, 0x8b, 0xff, 0x45, 0x1e, 0xa6, 0xf5, 0x06, - 0x93, 0x75, 0x28, 0xd7, 0x5c, 0x27, 0x74, 0xec, 0xb6, 0x6e, 0xaf, 0x2b, 0x2e, 0xea, 0x0e, 0x2f, - 0xb3, 0x32, 0xed, 0x76, 0x53, 0x94, 0x6c, 0xce, 0xb0, 0xa1, 0x0b, 0x42, 0x6e, 0x26, 0xc2, 0xa3, - 0x07, 0x8b, 0x45, 0xfc, 0x3c, 0x0f, 0x56, 0x1d, 0x97, 0x5a, 0x3c, 0x5e, 0xb7, 0x1e, 0x19, 0x35, - 0x49, 0x4c, 0x1e, 0x02, 0xd9, 0xe8, 0x05, 0x21, 0x2f, 0xa1, 0xfe, 0x0a, 0xdd, 0xf1, 0xfc, 0x61, - 0x02, 0xb5, 0xbc, 0x22, 0x3a, 0xe7, 0xb9, 0x4e, 0x2f, 0x08, 0x2d, 0x5f, 0x90, 0x5b, 0xdb, 0x48, - 0x9f, 0xe8, 0xa4, 0x8c, 0x1a, 0x16, 0x37, 0xa0, 0xa4, 0x8e, 0x1a, 0x9a, 0xcd, 0x39, 0x1d, 0x47, - 0x7a, 0x38, 0x70, 0xb3, 0x39, 0x06, 0x30, 0x39, 0x9c, 0x3c, 0x2b, 0x22, 0x9b, 0xe5, 0x63, 0xeb, - 0xb2, 0x38, 0x82, 0x99, 0xf1, 0x23, 0x39, 0x38, 0x9d, 0x6d, 0x72, 0x45, 0x3e, 0x4c, 0x3c, 0x0d, - 0xe7, 0x06, 0x3d, 0x9c, 0x4b, 0x3b, 0xad, 0x8f, 0xf6, 0x38, 0x6c, 0xfc, 0xb5, 0x91, 0x94, 0x94, - 0x95, 0xc1, 0x91, 0xdc, 0xcc, 0x1c, 0xc7, 0x9c, 0x72, 0x2e, 0xa6, 0xc7, 0x31, 0x73, 0xf4, 0xde, - 0x86, 0x69, 0x64, 0x1c, 0x4f, 0x2e, 0x45, 0xa9, 0xcc, 0x3f, 0x39, 0x9e, 0x5a, 0x66, 0x02, 0x97, - 0xd4, 0x80, 0x20, 0x64, 0xc5, 0x0b, 0x95, 0x88, 0x02, 0xca, 0xcd, 0x9a, 0x73, 0xd8, 0xf6, 0x42, - 0x4b, 0x8d, 0x2d, 0x90, 0x41, 0x44, 0x3e, 0x0f, 0x53, 0x72, 0x38, 0x57, 0xf1, 0x56, 0x33, 0x82, - 0xc3, 0x88, 0xd7, 0x34, 0xb9, 0x16, 0x2d, 0x14, 0x45, 0x4d, 0x1d, 0x91, 0x74, 0x78, 0x8c, 0x29, - 0x01, 0xa4, 0xad, 0x4a, 0x38, 0x44, 0x20, 0xaf, 0x97, 0xc5, 0xec, 0x7b, 0x86, 0xa7, 0x4d, 0x93, - 0xb4, 0x96, 0x1d, 0x26, 0xa6, 0x5e, 0x92, 0x37, 0xd9, 0x85, 0x29, 0x25, 0x9d, 0x5a, 0x25, 0x1c, - 0x22, 0x9b, 0xdf, 0x4b, 0xa2, 0xb2, 0xb3, 0x6a, 0x8e, 0xb6, 0x74, 0x55, 0x3a, 0x5f, 0xe3, 0x5b, - 0x79, 0x98, 0xe6, 0x97, 0x58, 0x6e, 0x77, 0xf7, 0xd4, 0x1a, 0x48, 0xbe, 0xa5, 0x19, 0x48, 0xca, - 0x90, 0xf9, 0x6a, 0xd3, 0x86, 0x32, 0x67, 0xdf, 0x03, 0x92, 0xa6, 0x21, 0x26, 0x94, 0x54, 0xe8, - 0x60, 0x63, 0xc6, 0xab, 0x71, 0x76, 0x05, 0xa1, 0x9d, 0x40, 0xf3, 0xd4, 0xc0, 0xd4, 0x78, 0x18, - 0x3f, 0x9e, 0x87, 0x29, 0xc5, 0x9c, 0xfd, 0xa9, 0xed, 0xf8, 0x37, 0xb5, 0x8e, 0x5f, 0x88, 0x42, - 0xaa, 0x44, 0x2d, 0x1b, 0xaa, 0xdf, 0x7b, 0x30, 0x9b, 0x22, 0x49, 0x7a, 0x05, 0xe4, 0x86, 0xf1, - 0x0a, 0x78, 0x35, 0x1d, 0xaa, 0x9d, 0x27, 0x6a, 0x8c, 0x02, 0xf7, 0xaa, 0xb1, 0xe1, 0x7f, 0x32, - 0x0f, 0xf3, 0xe2, 0x17, 0xe6, 0x36, 0xe1, 0xea, 0x98, 0xa7, 0x76, 0x2c, 0x2a, 0xda, 0x58, 0x2c, - 0xe9, 0x63, 0xa1, 0x34, 0xb0, 0xff, 0x90, 0x18, 0x3f, 0x02, 0xb0, 0xd0, 0x8f, 0x60, 0xe8, 0x58, - 0x6b, 0x71, 0x2c, 0x97, 0xfc, 0x10, 0xb1, 0x5c, 0xd6, 0xa1, 0x8c, 0x55, 0x09, 0x87, 0xaf, 0x60, - 0xcb, 0xac, 0x89, 0x4e, 0x42, 0xe9, 0x83, 0x27, 0xa0, 0x11, 0x5e, 0x62, 0x41, 0xe2, 0xe9, 0x22, - 0x45, 0x49, 0x7e, 0x29, 0x07, 0xd3, 0x08, 0x5c, 0x7b, 0xc8, 0xc4, 0x4d, 0xc6, 0x6c, 0x44, 0x04, - 0xf9, 0x88, 0x4c, 0x1e, 0x1b, 0xa1, 0xef, 0xb8, 0xbb, 0xc2, 0xe6, 0x71, 0x5b, 0xd8, 0x3c, 0xbe, - 0xcd, 0x6d, 0x35, 0x2f, 0x37, 0xbd, 0xce, 0x95, 0x5d, 0xdf, 0x7e, 0xe8, 0x70, 0x4f, 0x0d, 0xbb, - 0x7d, 0x25, 0xce, 0x2f, 0xdc, 0x75, 0x12, 0x99, 0x7f, 0x05, 0x2b, 0xb4, 0x27, 0xe5, 0x1f, 0x4a, - 0xb1, 0xda, 0xe4, 0x0b, 0x8b, 0xfe, 0x45, 0xe4, 0x07, 0xe0, 0x0c, 0xd7, 0x55, 0xaf, 0x7a, 0x6e, - 0xe8, 0xb8, 0x3d, 0xaf, 0x17, 0xac, 0xd8, 0xcd, 0xfd, 0x5e, 0x37, 0x10, 0xa1, 0x98, 0xb0, 0xe5, - 0xcd, 0xa8, 0xd0, 0xda, 0xe6, 0xa5, 0x5a, 0x38, 0xc4, 0x6c, 0x06, 0xe4, 0x16, 0xcc, 0xf2, 0xa2, - 0x4a, 0x2f, 0xf4, 0x1a, 0x4d, 0xbb, 0xcd, 0x04, 0xe2, 0x71, 0xe4, 0xca, 0x0d, 0xbb, 0x7a, 0xa1, - 0x67, 0x05, 0x1c, 0xae, 0x3e, 0xb8, 0xa4, 0x88, 0x48, 0x0d, 0x66, 0x4c, 0x6a, 0xb7, 0x36, 0xec, - 0xc7, 0xab, 0x76, 0xd7, 0x6e, 0x3a, 0x21, 0x4f, 0x72, 0x52, 0xe0, 0x2a, 0x05, 0x9f, 0xda, 0x2d, - 0xab, 0x63, 0x3f, 0xb6, 0x9a, 0xa2, 0x50, 0x7f, 0xb4, 0xd7, 0xe8, 0x22, 0x56, 0x8e, 0x1b, 0xb1, - 0x9a, 0x48, 0xb2, 0x72, 0xdc, 0xfe, 0xac, 0x62, 0x3a, 0xc9, 0x8a, 0x67, 0x9b, 0xe3, 0xce, 0xa9, - 0x70, 0x3e, 0x77, 0x31, 0xa7, 0xb0, 0x12, 0x29, 0xea, 0xd0, 0x51, 0x35, 0xc9, 0x4a, 0xa1, 0x63, - 0x33, 0xef, 0x81, 0xef, 0x84, 0x54, 0x6d, 0xe1, 0x24, 0x7e, 0x16, 0xf6, 0x3f, 0xba, 0xf5, 0xf6, - 0x6b, 0x62, 0x8a, 0x32, 0xe6, 0xa6, 0x34, 0xb2, 0x94, 0xe2, 0x96, 0xdd, 0xca, 0x14, 0x65, 0xc4, - 0x4d, 0x6d, 0xe7, 0x14, 0xb6, 0x53, 0xe1, 0xd6, 0xa7, 0xa1, 0x29, 0x4a, 0x72, 0x97, 0x75, 0x5a, - 0xc8, 0x6e, 0xee, 0x9e, 0x2b, 0xbc, 0x66, 0xa7, 0xf1, 0xd3, 0x5e, 0x14, 0x62, 0x43, 0xd9, 0x97, - 0xc5, 0x56, 0x86, 0x0f, 0x6d, 0x92, 0x98, 0xfc, 0x25, 0x98, 0xd9, 0x0a, 0xe8, 0x8d, 0x5a, 0xbd, - 0x21, 0x83, 0x64, 0xe3, 0x1b, 0xe1, 0xf4, 0xf2, 0xd5, 0x63, 0x36, 0x9d, 0xcb, 0x2a, 0x0d, 0xa6, - 0xeb, 0xe5, 0xe3, 0xd6, 0x0b, 0xa8, 0xb5, 0xe3, 0x74, 0x83, 0x28, 0x9f, 0x83, 0x3a, 0x6e, 0x89, - 0xaa, 0x8c, 0x5b, 0x30, 0x9b, 0x62, 0x43, 0xa6, 0x01, 0x18, 0xd0, 0xda, 0xba, 0xdb, 0x58, 0xdb, - 0x2c, 0x7f, 0x8a, 0x94, 0xa1, 0x84, 0xbf, 0xd7, 0xee, 0x56, 0x56, 0xd6, 0xd7, 0xaa, 0xe5, 0x1c, - 0x99, 0x85, 0x29, 0x84, 0x54, 0x6b, 0x0d, 0x0e, 0xca, 0xf3, 0x2c, 0x8b, 0x66, 0x99, 0x2f, 0xdd, - 0x10, 0x5f, 0x97, 0xd8, 0x99, 0x62, 0xfc, 0xcd, 0x3c, 0x9c, 0x95, 0xc7, 0x0a, 0x0d, 0x1f, 0x79, - 0xfe, 0xbe, 0xe3, 0xee, 0x3e, 0xe5, 0xa7, 0xc3, 0x0d, 0xed, 0x74, 0x78, 0x31, 0x71, 0x52, 0x27, - 0x5a, 0x39, 0xe0, 0x88, 0xf8, 0xce, 0x04, 0x9c, 0x1b, 0x48, 0x45, 0xde, 0x67, 0xa7, 0xb9, 0x43, - 0xdd, 0xb0, 0xd6, 0x6a, 0x53, 0x26, 0xa2, 0x7a, 0xbd, 0x50, 0x78, 0x69, 0xbf, 0x80, 0x4f, 0x68, - 0x58, 0x68, 0x39, 0xad, 0x36, 0xb5, 0x42, 0x5e, 0xac, 0x4d, 0xb7, 0x34, 0x35, 0x63, 0x19, 0xa5, - 0x0e, 0xaf, 0xb9, 0x21, 0xf5, 0x1f, 0xa2, 0xf3, 0x52, 0xc4, 0x72, 0x9f, 0xd2, 0xae, 0x65, 0xb3, - 0x52, 0xcb, 0x11, 0xc5, 0x3a, 0xcb, 0x14, 0x35, 0xb9, 0xa1, 0xb0, 0x44, 0x29, 0x7f, 0xc3, 0x7e, - 0x2c, 0x1c, 0x20, 0x44, 0x4a, 0x9b, 0x88, 0x25, 0x8f, 0x7f, 0xd2, 0xb1, 0x1f, 0x9b, 0x69, 0x12, - 0xf2, 0x15, 0x38, 0x25, 0x0e, 0x20, 0x11, 0x9f, 0x53, 0xb6, 0x98, 0x47, 0xff, 0x7c, 0x99, 0x5d, - 0xcc, 0xa4, 0x93, 0xb3, 0x8c, 0xb9, 0x9b, 0xd5, 0xea, 0x6c, 0x2e, 0x64, 0x93, 0x1d, 0xc8, 0x89, - 0xee, 0xd8, 0xa0, 0x41, 0x20, 0x83, 0xdc, 0x08, 0xdd, 0xac, 0xda, 0x99, 0x56, 0x87, 0x97, 0x9b, - 0x7d, 0x29, 0xc9, 0x2d, 0x98, 0x7e, 0x40, 0xb7, 0xd5, 0xf1, 0x19, 0x8b, 0xb6, 0xaa, 0xf2, 0x23, - 0xba, 0xdd, 0x7f, 0x70, 0x12, 0x74, 0xc4, 0xc1, 0x67, 0xfe, 0xc7, 0x07, 0xeb, 0xec, 0xe2, 0xec, - 0x52, 0x1f, 0xef, 0xbf, 0xe3, 0xb8, 0x19, 0x2c, 0xc4, 0x12, 0xb2, 0x5e, 0x2e, 0x74, 0x47, 0x18, - 0x57, 0xa2, 0x2d, 0xe0, 0x56, 0x22, 0xf1, 0x76, 0x9a, 0x2b, 0xf9, 0x1a, 0xcc, 0x98, 0x5e, 0x2f, - 0x74, 0xdc, 0xdd, 0x06, 0xbb, 0x61, 0xd2, 0x5d, 0x7e, 0x20, 0xc5, 0x21, 0xc4, 0x13, 0xa5, 0xc2, - 0xb8, 0x8c, 0x03, 0xad, 0x40, 0x40, 0xb5, 0x13, 0x41, 0x27, 0x20, 0x5f, 0x85, 0x69, 0x1e, 0xe7, - 0x30, 0xaa, 0x60, 0x42, 0xcb, 0xbe, 0xa9, 0x17, 0xde, 0xbf, 0x2a, 0xec, 0xd5, 0x11, 0x9a, 0x55, - 0x41, 0x82, 0x1b, 0xf9, 0x92, 0xe8, 0xac, 0xba, 0xe3, 0xee, 0x46, 0xd3, 0x18, 0xb0, 0xe7, 0x5f, - 0x8b, 0xbb, 0xa4, 0xcb, 0x3e, 0x57, 0x4e, 0xe3, 0x3e, 0xce, 0x37, 0x69, 0x3e, 0x24, 0x84, 0x73, - 0x95, 0x20, 0x70, 0x82, 0x50, 0xc4, 0x32, 0x58, 0x7b, 0x4c, 0x9b, 0x3d, 0x86, 0xfc, 0xc0, 0xf3, - 0xf7, 0xa9, 0xcf, 0xdd, 0x3f, 0x47, 0x57, 0x2e, 0x1f, 0x1d, 0x2e, 0xbd, 0x62, 0x23, 0xa2, 0x25, - 0xc2, 0x1f, 0x58, 0x54, 0xa2, 0x5a, 0x8f, 0x38, 0xae, 0xd2, 0x86, 0xc1, 0x4c, 0xc9, 0x57, 0xe1, - 0xf4, 0xaa, 0x1d, 0xd0, 0x9a, 0x1b, 0x50, 0x37, 0x70, 0x42, 0xe7, 0x21, 0x15, 0x9d, 0x8a, 0x87, - 0x5f, 0x91, 0xc7, 0x8e, 0x6f, 0xda, 0x01, 0x5b, 0x98, 0x11, 0x8a, 0x25, 0x06, 0x45, 0x0d, 0x4d, - 0x9f, 0xcd, 0x85, 0x98, 0x30, 0xdd, 0x68, 0xdc, 0xaa, 0x3a, 0x76, 0xb4, 0xae, 0xa6, 0xb0, 0xbf, - 0x5e, 0xc1, 0xc7, 0xa5, 0x60, 0xcf, 0x6a, 0x39, 0x76, 0xb4, 0xa0, 0xfa, 0x74, 0x56, 0x82, 0x83, - 0x71, 0x98, 0x83, 0x72, 0x72, 0x28, 0xc9, 0x07, 0x30, 0xc1, 0x3d, 0x57, 0x68, 0xb0, 0x27, 0xf4, - 0x2f, 0xd2, 0x11, 0x22, 0x82, 0xeb, 0x44, 0x22, 0x3c, 0x12, 0xf7, 0x8b, 0xa1, 0xaa, 0xbd, 0xec, - 0xad, 0x4f, 0x99, 0x31, 0x33, 0xd2, 0x82, 0x12, 0x1f, 0x2d, 0x8a, 0xe9, 0x0f, 0x12, 0x11, 0x1e, - 0xd4, 0xa2, 0x04, 0x7f, 0x6e, 0x25, 0xce, 0xe7, 0x04, 0x47, 0xd0, 0xaa, 0xd0, 0xb8, 0xae, 0x00, - 0x14, 0x25, 0xa1, 0x71, 0x16, 0xce, 0xf4, 0xf9, 0x66, 0xe3, 0x21, 0xea, 0x9c, 0xfb, 0xd4, 0x48, - 0x3e, 0x80, 0x79, 0x24, 0x5c, 0xf5, 0x5c, 0x97, 0x36, 0x43, 0xdc, 0x8e, 0xe4, 0xfb, 0x6f, 0x81, - 0xdb, 0xba, 0xf2, 0xf6, 0x36, 0x23, 0x04, 0x2b, 0xf9, 0x0c, 0x9c, 0xc9, 0xc1, 0xf8, 0xf9, 0x3c, - 0x2c, 0x88, 0x1d, 0xce, 0xa4, 0x4d, 0x0f, 0xb5, 0x8f, 0x4f, 0xf9, 0x89, 0xba, 0xa6, 0x9d, 0xa8, - 0x2f, 0x44, 0x71, 0x5e, 0xb3, 0x1a, 0x39, 0xe0, 0x40, 0xfd, 0xb5, 0x1c, 0x3c, 0x3b, 0x88, 0x28, - 0xd2, 0x2a, 0xe6, 0xb2, 0xb4, 0x8a, 0xa4, 0x0b, 0x73, 0x38, 0xa0, 0xab, 0x7b, 0xb4, 0xb9, 0x8f, - 0xa1, 0x69, 0xd0, 0x21, 0x3b, 0xdf, 0xc7, 0x64, 0xed, 0xd5, 0x4c, 0x93, 0xb5, 0xd3, 0x7c, 0x96, - 0x35, 0x91, 0x07, 0x8f, 0x7a, 0xb3, 0x4f, 0x0f, 0x02, 0x33, 0x8b, 0xb5, 0xf1, 0xd3, 0x79, 0x76, - 0x65, 0x0b, 0xf7, 0xea, 0x3e, 0xdd, 0xa1, 0x3e, 0x75, 0x9b, 0xf4, 0xfb, 0xcc, 0xb1, 0x56, 0x6f, - 0xdc, 0x50, 0x1a, 0x8c, 0x6f, 0x4f, 0xc3, 0x7c, 0x16, 0x19, 0xeb, 0x17, 0xe5, 0xd2, 0x5c, 0x94, - 0x91, 0x10, 0xc4, 0x55, 0xf9, 0x9b, 0x39, 0x28, 0x35, 0x68, 0xd3, 0x73, 0x5b, 0x37, 0xd0, 0xa6, - 0x58, 0xf4, 0x8e, 0xcd, 0x85, 0x06, 0x06, 0xb7, 0x76, 0x12, 0xc6, 0xc6, 0xdf, 0x3b, 0x5c, 0xfa, - 0xc2, 0x70, 0x77, 0xd5, 0xa6, 0x87, 0xba, 0xcf, 0x10, 0x53, 0x65, 0x46, 0x55, 0xf0, 0xaf, 0x31, - 0xb5, 0x6a, 0xc9, 0x0a, 0x4c, 0x89, 0x05, 0xeb, 0xa9, 0x09, 0x33, 0x78, 0x30, 0x5c, 0x59, 0x90, - 0x7a, 0x3e, 0xd5, 0x48, 0xc8, 0x35, 0x28, 0x6c, 0x2d, 0xdf, 0x10, 0xa3, 0x20, 0x83, 0x3e, 0x6d, - 0x2d, 0xdf, 0x40, 0x85, 0x18, 0xbb, 0x64, 0x4c, 0xf5, 0x96, 0x35, 0x6b, 0xdd, 0xad, 0xe5, 0x1b, - 0xe4, 0x2f, 0xc3, 0xa9, 0xaa, 0x13, 0x88, 0x2a, 0xb8, 0x93, 0x77, 0x0b, 0xa3, 0x9e, 0x8c, 0xf5, - 0x99, 0xbf, 0x9f, 0xcb, 0x9c, 0xbf, 0xcf, 0xb7, 0x22, 0x26, 0x16, 0xf7, 0x20, 0x6f, 0x25, 0x13, - 0x83, 0x64, 0xd7, 0x43, 0x3e, 0x84, 0x69, 0x7c, 0x1b, 0x43, 0xbf, 0x77, 0x4c, 0xb8, 0x37, 0xde, - 0xa7, 0xe6, 0xcf, 0x64, 0xd6, 0xbc, 0xc8, 0xed, 0x6b, 0xd0, 0x7b, 0x1e, 0x93, 0xf3, 0x69, 0xf7, - 0x7e, 0x8d, 0x33, 0xb9, 0x0d, 0x33, 0x42, 0x00, 0xbb, 0xb7, 0xb3, 0xb9, 0x47, 0xab, 0xf6, 0x81, - 0x30, 0xb4, 0xc5, 0x3b, 0x9d, 0x90, 0xda, 0x2c, 0x6f, 0xc7, 0x0a, 0xf7, 0xa8, 0xd5, 0xb2, 0x35, - 0x51, 0x25, 0x41, 0x48, 0xbe, 0x01, 0x93, 0xeb, 0x5e, 0x93, 0xc9, 0xde, 0xb8, 0x37, 0x70, 0xdb, - 0xdb, 0x2f, 0xb2, 0xa5, 0xdc, 0xe6, 0xe0, 0x84, 0x40, 0xf5, 0xbd, 0xc3, 0xa5, 0xb7, 0x4e, 0x3a, - 0x6d, 0x94, 0x0a, 0x4c, 0xb5, 0x36, 0xb2, 0x0a, 0xc5, 0x07, 0x74, 0x9b, 0xb5, 0x36, 0x99, 0x7a, - 0x5f, 0x82, 0x85, 0x55, 0xbe, 0xf8, 0xa5, 0x59, 0xe5, 0x0b, 0x18, 0xf1, 0x61, 0x16, 0xfb, 0xa7, - 0x6e, 0x07, 0xc1, 0x23, 0xcf, 0x6f, 0x61, 0xce, 0xd3, 0x7e, 0x66, 0xbd, 0xcb, 0x99, 0x9d, 0xff, - 0x2c, 0xef, 0xfc, 0xae, 0xc2, 0x41, 0x15, 0x21, 0x53, 0xec, 0xc9, 0xd7, 0x60, 0x5a, 0x84, 0x7b, - 0xdb, 0xb8, 0x51, 0xc1, 0x95, 0x50, 0xd2, 0x02, 0xc4, 0xe8, 0x85, 0xf2, 0xbd, 0x0a, 0x61, 0x51, - 0xa4, 0xa2, 0xce, 0x8e, 0xad, 0x3f, 0x3c, 0xab, 0x24, 0xa4, 0x0e, 0x93, 0x55, 0xfa, 0xd0, 0x69, - 0x52, 0x0c, 0x62, 0x21, 0x7c, 0x3e, 0xa3, 0x5c, 0xde, 0x71, 0x09, 0xd7, 0xc6, 0xb4, 0x10, 0xc0, - 0x43, 0x62, 0xe8, 0xfe, 0x3a, 0x11, 0x22, 0xb9, 0x0e, 0x85, 0x5a, 0xb5, 0x2e, 0x5c, 0x3e, 0x67, - 0xa3, 0xa0, 0x8a, 0x75, 0x99, 0xf9, 0x18, 0x0d, 0xe1, 0x9d, 0x96, 0xe6, 0x30, 0x5a, 0xab, 0xd6, - 0xc9, 0x0e, 0x4c, 0x71, 0x03, 0x2f, 0x6a, 0xf3, 0xbe, 0x9d, 0xe9, 0xd3, 0xb7, 0x97, 0x33, 0xfb, - 0x76, 0x41, 0x18, 0x8e, 0x09, 0x6a, 0x2d, 0x95, 0xab, 0xca, 0x96, 0x09, 0xb5, 0x22, 0xbd, 0xb4, - 0x4c, 0x40, 0xba, 0xb9, 0x8e, 0x86, 0xbe, 0x42, 0xa8, 0x95, 0xd9, 0xa8, 0xa3, 0x8c, 0xa8, 0x7d, - 0x3d, 0xca, 0xd3, 0x7c, 0xc8, 0x9b, 0x30, 0x72, 0x6f, 0x3f, 0xb4, 0x85, 0x73, 0xa7, 0xec, 0x47, - 0x06, 0x92, 0xcd, 0xe7, 0x16, 0x7a, 0xfb, 0x5a, 0x98, 0x6e, 0xa4, 0x61, 0x43, 0x71, 0xcb, 0xf6, - 0x5b, 0x8f, 0x6c, 0x1f, 0x23, 0x09, 0xcd, 0x69, 0x2c, 0x94, 0x12, 0x3e, 0x14, 0x7b, 0x02, 0x90, - 0x78, 0xe0, 0x54, 0x59, 0x90, 0x1f, 0x80, 0xb3, 0x81, 0xb3, 0xeb, 0xda, 0x21, 0x37, 0xac, 0xdb, - 0xf5, 0x7c, 0x27, 0xdc, 0xeb, 0x58, 0x41, 0xcf, 0x09, 0x29, 0x7a, 0x59, 0x4e, 0x47, 0x32, 0x63, - 0x43, 0xe2, 0x55, 0x24, 0x5a, 0x83, 0x61, 0x99, 0x67, 0x82, 0xec, 0x02, 0xf2, 0x25, 0x98, 0x52, - 0xb7, 0xe4, 0x60, 0xe1, 0xd4, 0xf9, 0xc2, 0xc5, 0xe9, 0xe8, 0xea, 0x91, 0xdc, 0xc2, 0x65, 0x9a, - 0x20, 0xe5, 0x8c, 0x08, 0xf4, 0x34, 0x41, 0x0a, 0x2f, 0x62, 0xc2, 0x99, 0x80, 0xeb, 0x37, 0x7a, - 0xae, 0xf3, 0x18, 0x23, 0xda, 0x09, 0x83, 0xf0, 0x85, 0xd3, 0xda, 0xd1, 0xd7, 0x40, 0xac, 0xad, - 0xbb, 0xb5, 0x0f, 0xb6, 0x02, 0xea, 0x0b, 0xbb, 0xf0, 0x79, 0x4e, 0xbb, 0xe5, 0x3a, 0x8f, 0x63, - 0x28, 0x57, 0x9e, 0xdc, 0x1e, 0x29, 0x92, 0xf2, 0x9c, 0x39, 0x2b, 0x56, 0x81, 0x18, 0xb9, 0x8d, - 0x1b, 0x15, 0x73, 0xbc, 0x5e, 0xbb, 0xdf, 0x68, 0x7b, 0xa1, 0xb1, 0x07, 0xf3, 0x59, 0x5c, 0xc9, - 0x02, 0x8c, 0x8b, 0x7c, 0x8b, 0x78, 0x38, 0x16, 0x4d, 0xf9, 0x93, 0x3c, 0x03, 0x13, 0x3b, 0x8e, - 0x1f, 0x84, 0x56, 0xcf, 0xe1, 0xf2, 0xc2, 0xa8, 0x59, 0x44, 0xc0, 0x96, 0xd3, 0x22, 0x67, 0xa1, - 0x88, 0x6f, 0x5c, 0xac, 0xac, 0x80, 0x65, 0xe3, 0xec, 0xf7, 0x96, 0xd3, 0x32, 0xfe, 0xdb, 0x1c, - 0x1e, 0x41, 0xe4, 0x15, 0x8c, 0x1c, 0x1c, 0xd9, 0x9f, 0xa0, 0xfe, 0xd9, 0xee, 0x26, 0xf2, 0x17, - 0x72, 0x14, 0xf2, 0x2a, 0x8c, 0xdd, 0xb0, 0x9b, 0x34, 0x32, 0x6b, 0x40, 0xe4, 0x1d, 0x84, 0xa8, - 0xca, 0x6a, 0x8e, 0xc3, 0xe4, 0x63, 0xbe, 0x34, 0x2b, 0x61, 0x48, 0x03, 0xbe, 0x7f, 0xae, 0x56, - 0xa4, 0x29, 0x03, 0xca, 0xc7, 0x62, 0x49, 0xdb, 0x31, 0x42, 0xc2, 0xaf, 0x2f, 0x93, 0x83, 0xf1, - 0x27, 0xb9, 0x78, 0x4f, 0x25, 0x2f, 0xc3, 0x88, 0x59, 0x8f, 0xbe, 0x9f, 0xc7, 0x36, 0x4a, 0x7c, - 0x3e, 0x22, 0x90, 0x2f, 0xc1, 0x29, 0x85, 0x4f, 0xca, 0xc9, 0xf0, 0x25, 0x0c, 0xbd, 0xa3, 0x7c, - 0x49, 0xb6, 0xa7, 0x61, 0x36, 0x0f, 0xbc, 0x0c, 0xc4, 0x05, 0x55, 0xea, 0x3a, 0x9c, 0xb7, 0xd2, - 0x58, 0x95, 0x77, 0x0b, 0x11, 0x92, 0x8d, 0xcd, 0xe2, 0xc0, 0x23, 0xef, 0x18, 0xbf, 0x95, 0xd3, - 0xf6, 0x4a, 0x72, 0x41, 0x93, 0x73, 0x71, 0x5d, 0x27, 0x94, 0x02, 0x5c, 0xe2, 0x7d, 0x03, 0xa0, - 0xd2, 0x0b, 0xbd, 0x35, 0xd7, 0xf7, 0xda, 0x6d, 0x61, 0xf3, 0xca, 0x63, 0x7a, 0xf4, 0x42, 0xcf, - 0xa2, 0x08, 0xd6, 0x62, 0x7a, 0x44, 0xc8, 0x99, 0xfe, 0x98, 0x85, 0x8f, 0xea, 0x8f, 0x69, 0xfc, - 0x5c, 0x5e, 0xdb, 0x61, 0x98, 0x94, 0x2b, 0x26, 0xbd, 0x6a, 0x64, 0xde, 0x75, 0x1e, 0x5a, 0x41, - 0xdb, 0xd3, 0x42, 0x1c, 0x0a, 0x34, 0xf2, 0xd7, 0x72, 0x70, 0x9a, 0x3b, 0x36, 0xde, 0xed, 0x75, - 0xb6, 0xa9, 0x7f, 0xdf, 0x6e, 0x3b, 0xad, 0x38, 0x2e, 0x7b, 0xec, 0xc5, 0xa0, 0x54, 0x93, 0x8d, - 0xcf, 0x2f, 0xda, 0xdc, 0xd1, 0xd2, 0x72, 0xb1, 0xd0, 0x7a, 0x18, 0x95, 0xaa, 0x17, 0xed, 0x6c, - 0x7a, 0x52, 0x83, 0xc9, 0xba, 0xe3, 0x62, 0x7a, 0xdb, 0x38, 0x14, 0xc8, 0xcb, 0xdc, 0x4f, 0x99, - 0x4d, 0xe1, 0xe6, 0x1e, 0x1d, 0xb0, 0x75, 0xab, 0xb4, 0xc6, 0xaf, 0xe7, 0xe0, 0xf9, 0x63, 0x3f, - 0x98, 0x5c, 0x81, 0xf1, 0x35, 0x75, 0xfd, 0x73, 0x4b, 0xa0, 0x74, 0x0a, 0x56, 0x89, 0x45, 0xbe, - 0x0c, 0xa7, 0x54, 0x56, 0x9b, 0xbe, 0xed, 0xa8, 0x2e, 0xd9, 0x19, 0x1d, 0x10, 0x32, 0x94, 0xa4, - 0xd8, 0x9a, 0xcd, 0xc4, 0xf8, 0x7f, 0x72, 0x30, 0x11, 0xf9, 0x74, 0x3d, 0xa5, 0xd7, 0x99, 0xeb, - 0xda, 0x75, 0x46, 0x26, 0xb8, 0x88, 0x5a, 0xc5, 0x4d, 0x8f, 0x32, 0xae, 0xa0, 0x33, 0x8a, 0x07, - 0x1c, 0x02, 0x7e, 0x34, 0x0f, 0x93, 0x6c, 0xab, 0xe6, 0x6f, 0xda, 0xdf, 0x5f, 0x61, 0xfe, 0xa3, - 0x76, 0x0d, 0x15, 0x88, 0xfd, 0xdf, 0xe4, 0xf0, 0xad, 0x43, 0xa5, 0x60, 0xbd, 0xc1, 0x40, 0x6a, - 0x6f, 0xb0, 0x13, 0xd5, 0x44, 0x28, 0x0f, 0x4b, 0xbd, 0x2e, 0x7a, 0x42, 0x84, 0xa5, 0x6e, 0x9b, - 0x0c, 0x46, 0xbe, 0x00, 0xa3, 0x5b, 0xa8, 0xb9, 0xd5, 0xc3, 0x12, 0x46, 0xfc, 0xb1, 0x90, 0xef, - 0xf7, 0xbd, 0x40, 0x8f, 0x59, 0xce, 0x09, 0x49, 0x03, 0xc6, 0x57, 0x7d, 0x6a, 0x87, 0xb4, 0x25, - 0x3a, 0x64, 0xa8, 0xa0, 0x5a, 0x4d, 0x4e, 0x92, 0x0c, 0xaa, 0x25, 0x38, 0xb1, 0x7d, 0x8c, 0xc4, - 0x6d, 0x44, 0xab, 0x9d, 0xe0, 0xa9, 0x1d, 0xf4, 0xf7, 0xb4, 0x41, 0x3f, 0x97, 0x1a, 0x74, 0xde, - 0xbc, 0xa1, 0xc6, 0xfe, 0xb7, 0x73, 0x70, 0x3a, 0x9b, 0x90, 0xbc, 0x00, 0x63, 0xf7, 0x36, 0xeb, - 0xb1, 0xa5, 0x1c, 0x36, 0xc5, 0xeb, 0xa2, 0xda, 0xc4, 0x14, 0x45, 0xe4, 0x35, 0x18, 0x7b, 0xdf, - 0x5c, 0x8d, 0x0d, 0xc2, 0x70, 0x83, 0xfb, 0x3a, 0x93, 0xbc, 0xb4, 0x53, 0x4d, 0x20, 0xa9, 0x63, - 0x5b, 0x78, 0x62, 0x63, 0xfb, 0x93, 0x79, 0x98, 0xa9, 0x34, 0x9b, 0x34, 0x08, 0x44, 0x5a, 0xb5, - 0xa7, 0x76, 0x60, 0xb3, 0x63, 0x56, 0x6a, 0x6d, 0x1b, 0x6a, 0x54, 0x7f, 0x37, 0xc7, 0x43, 0xd4, - 0x32, 0xaa, 0x87, 0x0e, 0x7d, 0xb4, 0xb9, 0xe7, 0xd3, 0x60, 0xcf, 0x6b, 0xb7, 0x86, 0x4e, 0xeb, - 0xcb, 0x64, 0x46, 0x4c, 0x3d, 0xa6, 0x1a, 0x38, 0xec, 0x20, 0x44, 0x93, 0x19, 0x79, 0x7a, 0xb2, - 0x2b, 0x30, 0x5e, 0xe9, 0x76, 0x7d, 0xef, 0x21, 0x5f, 0xf6, 0x22, 0x2b, 0x81, 0xcd, 0x41, 0x5a, - 0x18, 0x31, 0x0e, 0x62, 0x9f, 0x51, 0xa5, 0xee, 0x81, 0x6a, 0x9e, 0xd6, 0xa2, 0xae, 0x7a, 0x29, - 0xc1, 0x72, 0xa3, 0x01, 0xa4, 0xee, 0x7b, 0x1d, 0x2f, 0xa4, 0x2d, 0xde, 0x1e, 0x8c, 0xbe, 0x76, - 0x6c, 0x44, 0xe7, 0x4d, 0x27, 0x6c, 0x6b, 0x11, 0x9d, 0x43, 0x06, 0x30, 0x39, 0x9c, 0x9d, 0xdd, - 0xe7, 0xb4, 0x3e, 0xad, 0xfa, 0x07, 0x66, 0xcf, 0x5d, 0x73, 0x7d, 0xa7, 0xb9, 0x87, 0x8e, 0xc2, - 0x77, 0x01, 0x4c, 0x6a, 0x07, 0x9e, 0xab, 0x08, 0x6b, 0x97, 0x79, 0x52, 0x63, 0x06, 0x4d, 0xeb, - 0x1d, 0x66, 0x05, 0xa7, 0x98, 0xca, 0x54, 0x38, 0x90, 0x0a, 0x4c, 0xf1, 0x5f, 0xac, 0x31, 0xdd, - 0x48, 0x10, 0x7f, 0x86, 0xbb, 0xed, 0x22, 0xcb, 0x2e, 0x96, 0xe8, 0x21, 0x3d, 0x14, 0x0a, 0xe3, - 0xff, 0x1c, 0x85, 0x92, 0x3a, 0xa4, 0xc4, 0xe0, 0x19, 0x3a, 0x3d, 0x5f, 0x0d, 0x82, 0x68, 0x23, - 0xc4, 0x14, 0x25, 0x71, 0x04, 0xd1, 0xfc, 0xb1, 0x11, 0x44, 0x1f, 0xc0, 0x54, 0xdd, 0xf7, 0x30, - 0xe7, 0x03, 0xbe, 0x36, 0x8b, 0xfd, 0x7b, 0x4e, 0xd1, 0x1a, 0xb0, 0xd9, 0x87, 0xef, 0xd9, 0x78, - 0x2f, 0xeb, 0x0a, 0x6c, 0x8b, 0x89, 0xbe, 0x9a, 0xce, 0x4c, 0xe3, 0xc3, 0x4d, 0x65, 0x58, 0x4b, - 0xd4, 0x4c, 0x46, 0xbc, 0xd1, 0xba, 0xa9, 0x0c, 0x83, 0xa8, 0x1b, 0xc4, 0xe8, 0x93, 0xda, 0x20, - 0xc8, 0xcf, 0xe5, 0x60, 0xb2, 0xe2, 0xba, 0x22, 0x32, 0xe9, 0x31, 0x71, 0xd4, 0xbe, 0x2c, 0xac, - 0x65, 0xde, 0xfa, 0x48, 0xd6, 0x32, 0x28, 0x6c, 0x05, 0x28, 0xa9, 0xc7, 0x15, 0x6a, 0xd1, 0x85, - 0x62, 0x30, 0x79, 0x0b, 0xca, 0xd1, 0xca, 0xac, 0xb9, 0x2d, 0xfa, 0x98, 0x06, 0x0b, 0xe3, 0xe7, - 0x0b, 0x17, 0xa7, 0x44, 0x22, 0x29, 0x55, 0x32, 0x4f, 0x22, 0x92, 0x4d, 0x00, 0x3b, 0x5a, 0x12, - 0xe2, 0x11, 0xef, 0x6c, 0xfc, 0xe0, 0x92, 0x58, 0x33, 0xe2, 0xf6, 0x80, 0xbf, 0xf1, 0x41, 0x52, - 0xbd, 0x3d, 0xc4, 0x7c, 0x48, 0x07, 0x66, 0x2a, 0x41, 0xd0, 0xeb, 0xd0, 0x46, 0x68, 0xfb, 0x21, - 0x66, 0x8b, 0x84, 0xe1, 0xcd, 0x40, 0x6d, 0x24, 0x65, 0x33, 0xc2, 0x0f, 0xad, 0x8c, 0xd4, 0x91, - 0x49, 0xde, 0x3c, 0x6d, 0x97, 0x79, 0x26, 0xfd, 0xbd, 0x7c, 0xa5, 0xfe, 0x64, 0x0e, 0x4e, 0xab, - 0x93, 0xbe, 0xd1, 0xdb, 0x16, 0xb9, 0x32, 0xc8, 0x65, 0x98, 0x10, 0x73, 0x32, 0xba, 0x44, 0xa6, - 0x93, 0x5e, 0xc6, 0x28, 0x64, 0x8d, 0x4d, 0x43, 0xc6, 0x43, 0xdc, 0x3a, 0xe6, 0x12, 0x9b, 0x2b, - 0x2b, 0x5a, 0x59, 0x88, 0xb3, 0x76, 0xb2, 0xdf, 0xfa, 0xfc, 0x64, 0x10, 0xe3, 0x5d, 0x98, 0xd5, - 0x47, 0xa2, 0x41, 0x43, 0x72, 0x09, 0xc6, 0xe5, 0xf0, 0xe5, 0xb2, 0x87, 0x4f, 0x96, 0x1b, 0x0f, - 0x80, 0xa4, 0xe8, 0x03, 0x34, 0x6b, 0x63, 0xf7, 0x73, 0x6e, 0x76, 0x29, 0x1f, 0x95, 0x53, 0x88, - 0x2b, 0x73, 0xe2, 0xfb, 0x26, 0x35, 0x7f, 0x4b, 0xcc, 0x1b, 0xf2, 0x2d, 0x02, 0x73, 0x19, 0x07, - 0xc5, 0x31, 0x82, 0xdc, 0x92, 0xbe, 0x41, 0x4c, 0x44, 0x61, 0x18, 0xe5, 0xb6, 0xf0, 0x2e, 0x8c, - 0x1e, 0xbb, 0x1d, 0x70, 0x3f, 0xde, 0xc4, 0x2e, 0xc0, 0xc9, 0x3e, 0x11, 0x61, 0x4e, 0x0d, 0xbb, - 0x3a, 0xfa, 0xc4, 0xc2, 0xae, 0x62, 0xdc, 0x25, 0x65, 0x13, 0xd7, 0x63, 0x41, 0xf1, 0x24, 0xae, - 0xa9, 0x6d, 0x4b, 0x27, 0xe1, 0x3c, 0x02, 0xaf, 0xfd, 0x90, 0x0a, 0x1e, 0xe3, 0x2a, 0x0f, 0x2c, - 0xc8, 0xe4, 0xa1, 0x90, 0x90, 0xbf, 0x9f, 0x03, 0x22, 0x20, 0xea, 0x9e, 0x55, 0x1c, 0xb4, 0x67, - 0xb5, 0x9e, 0xcc, 0x9e, 0x75, 0x4e, 0x7e, 0x63, 0xf6, 0xde, 0x95, 0xf1, 0x59, 0xe4, 0xef, 0xe6, - 0x60, 0x96, 0x87, 0xeb, 0x54, 0x3f, 0x76, 0x60, 0x08, 0xc6, 0xe6, 0x93, 0xf9, 0xd8, 0x67, 0x45, - 0xfa, 0xde, 0xec, 0x6f, 0x4d, 0x7f, 0x14, 0xf9, 0x01, 0x80, 0x68, 0x45, 0xf1, 0xdc, 0x29, 0x93, - 0xcb, 0xcf, 0x66, 0xec, 0x02, 0x11, 0x52, 0x9c, 0xb3, 0x32, 0x8c, 0xe8, 0xd4, 0x6d, 0x33, 0xe6, - 0x46, 0xfe, 0x32, 0xcf, 0x74, 0x10, 0x41, 0x44, 0xa4, 0xe2, 0x85, 0x49, 0xac, 0xe5, 0xb3, 0xfd, - 0x05, 0xb9, 0xcb, 0x59, 0x64, 0x3c, 0xd3, 0x4e, 0x64, 0x64, 0xed, 0x87, 0x9d, 0x64, 0xb6, 0x83, - 0x24, 0x05, 0x06, 0x00, 0xc7, 0xaf, 0xe7, 0x79, 0x25, 0xfb, 0xec, 0x6f, 0x67, 0xe5, 0x5a, 0xe0, - 0xfb, 0x5b, 0xc2, 0x19, 0x09, 0x41, 0xe4, 0x7d, 0x20, 0x51, 0x9c, 0x4b, 0x0e, 0xa3, 0x32, 0xe7, - 0x24, 0x7f, 0x2c, 0x88, 0xe3, 0x65, 0xfa, 0xb2, 0x58, 0x9d, 0x24, 0x69, 0x62, 0x42, 0x61, 0x5e, - 0x34, 0x9a, 0x41, 0xb9, 0x03, 0x71, 0xad, 0x1a, 0x2c, 0x4c, 0x6b, 0x71, 0xa0, 0xe3, 0x92, 0x95, - 0xe7, 0x64, 0x8a, 0xe6, 0xc8, 0x13, 0x59, 0x77, 0xe9, 0xcd, 0x64, 0x47, 0xae, 0xc3, 0x04, 0xc6, - 0x6b, 0xb9, 0x25, 0x8d, 0xf5, 0x84, 0xe1, 0x10, 0x46, 0x76, 0xb1, 0xf6, 0x74, 0x93, 0xbb, 0x18, - 0x95, 0xdd, 0x61, 0xb8, 0x04, 0x88, 0x2a, 0x7d, 0xa1, 0xa4, 0x69, 0xf9, 0x07, 0x96, 0xdf, 0xd3, - 0x63, 0x01, 0x21, 0x12, 0xf9, 0x1a, 0x4c, 0x6e, 0xd8, 0x8f, 0xa3, 0x54, 0xd0, 0xb3, 0xc3, 0x27, - 0x9c, 0xee, 0xd8, 0x8f, 0xa3, 0x3c, 0xd0, 0x49, 0x07, 0x26, 0x85, 0x25, 0xf9, 0x0a, 0x80, 0xf2, - 0xce, 0x40, 0x8e, 0xad, 0xe0, 0x79, 0x19, 0xdd, 0x3c, 0xf3, 0xfd, 0x01, 0xf9, 0x2b, 0x0c, 0x13, - 0x92, 0xc3, 0xfc, 0x27, 0x27, 0x39, 0x9c, 0xfa, 0xe4, 0x24, 0x07, 0xfe, 0xcc, 0xc5, 0xc7, 0x1e, - 0x77, 0xf0, 0x03, 0xa1, 0xe5, 0x1f, 0x54, 0xdb, 0xb3, 0xd2, 0x14, 0x14, 0x8f, 0x82, 0x83, 0x44, - 0x15, 0x09, 0x7e, 0xc4, 0x87, 0x72, 0xf2, 0x62, 0xb0, 0x70, 0x46, 0xb3, 0x2c, 0x1c, 0x78, 0x89, - 0xe0, 0xea, 0x56, 0x31, 0x8d, 0x2c, 0x1a, 0xc1, 0x55, 0xa1, 0x2e, 0x75, 0xf1, 0xb8, 0x0f, 0x93, - 0x82, 0x1d, 0x5e, 0x4e, 0x17, 0x34, 0x23, 0x33, 0xad, 0x3a, 0x56, 0xce, 0x5f, 0x75, 0xe4, 0xe1, - 0x94, 0xb8, 0xba, 0xaa, 0x8c, 0x48, 0x07, 0xca, 0xeb, 0x9e, 0xbb, 0xbb, 0x49, 0xfd, 0x0e, 0x7a, - 0xee, 0xb3, 0xbd, 0xe9, 0xac, 0x66, 0x43, 0x2f, 0x8b, 0x35, 0x07, 0x7f, 0xc7, 0xdd, 0xe5, 0xcd, - 0x68, 0x7b, 0xee, 0xae, 0x15, 0x52, 0xbf, 0xc3, 0x43, 0x02, 0xe8, 0x76, 0x4d, 0x29, 0xd6, 0x8b, - 0xdb, 0x70, 0xb6, 0xef, 0xbe, 0x96, 0x91, 0xf2, 0xe8, 0x8a, 0x9e, 0xf2, 0xe8, 0x6c, 0x3f, 0xf9, - 0x27, 0xd0, 0xf3, 0xbe, 0xce, 0x95, 0xe7, 0xfb, 0x8b, 0x8e, 0xdf, 0xcd, 0x27, 0xe4, 0x21, 0x71, - 0x55, 0xe5, 0x59, 0xd2, 0xfb, 0x09, 0x8c, 0xf9, 0x5a, 0x95, 0xdd, 0x4d, 0x51, 0x62, 0x52, 0xb2, - 0xd4, 0x31, 0x89, 0x49, 0x95, 0xb8, 0x50, 0x76, 0xfa, 0xb8, 0xa2, 0xd1, 0xdb, 0x30, 0xdd, 0xa0, - 0xb6, 0xdf, 0xdc, 0xbb, 0x43, 0x0f, 0x1e, 0x79, 0x7e, 0x8b, 0x67, 0x53, 0x16, 0x17, 0xa4, 0x00, - 0x4b, 0xf4, 0xc8, 0x13, 0x2a, 0x2e, 0xa9, 0xca, 0x58, 0x2a, 0xa3, 0x58, 0xfb, 0xd9, 0xcc, 0x23, - 0x86, 0x21, 0x0c, 0x0a, 0xb3, 0x42, 0x5e, 0x8f, 0xa4, 0x68, 0xea, 0xab, 0xd9, 0x5f, 0x7d, 0x09, - 0xcc, 0x10, 0xa6, 0xa9, 0x6f, 0xfc, 0x61, 0x01, 0x08, 0xaf, 0x69, 0xd5, 0xee, 0xda, 0x18, 0xbd, - 0xc8, 0xc1, 0x10, 0xc5, 0x65, 0x81, 0x63, 0x6f, 0xb7, 0xa9, 0x1a, 0xdf, 0x5b, 0x58, 0xae, 0x47, - 0x65, 0x56, 0xf2, 0x16, 0x9a, 0x22, 0xec, 0x73, 0x0e, 0xe5, 0x3f, 0xce, 0x39, 0xf4, 0x35, 0x78, - 0xa6, 0xd2, 0xed, 0xb6, 0x9d, 0x66, 0x54, 0xcb, 0x0d, 0xcf, 0x97, 0x13, 0x5e, 0x0b, 0xe9, 0x60, - 0x47, 0x68, 0xa9, 0x2f, 0x1d, 0xc4, 0x42, 0x11, 0x22, 0xf9, 0xbd, 0x5d, 0x8d, 0xb3, 0x26, 0xd7, - 0x69, 0xd6, 0x4d, 0x5f, 0x21, 0x91, 0x3c, 0x1c, 0x5f, 0x0a, 0x91, 0xa3, 0x71, 0x5a, 0x21, 0xf9, - 0x50, 0x9f, 0x2d, 0x88, 0x46, 0x24, 0xe4, 0x6d, 0x98, 0xac, 0xf4, 0x42, 0x4f, 0x30, 0x16, 0x2e, - 0x17, 0xb1, 0x73, 0x84, 0xf8, 0x14, 0xed, 0x5e, 0x1a, 0xa3, 0x1b, 0x7f, 0x5c, 0x80, 0xb3, 0xe9, - 0xe1, 0x15, 0xa5, 0xd1, 0xfa, 0xc8, 0x1d, 0xb3, 0x3e, 0xb2, 0x66, 0x43, 0x3e, 0xce, 0x7b, 0xf9, - 0x24, 0x66, 0x03, 0x8f, 0x9c, 0xf4, 0x11, 0x67, 0x43, 0x83, 0xed, 0xb5, 0xb1, 0x30, 0x32, 0xf2, - 0x51, 0x85, 0x11, 0x95, 0x0b, 0xb9, 0x04, 0xa3, 0x3c, 0xbc, 0xdc, 0x68, 0xfc, 0xae, 0x99, 0x8c, - 0x2c, 0xc7, 0x31, 0xc8, 0xff, 0x0f, 0xce, 0xf3, 0x3d, 0x29, 0xd9, 0xd8, 0x95, 0x03, 0xc9, 0x51, - 0x0c, 0xdc, 0xf2, 0xd1, 0xe1, 0xd2, 0x65, 0xae, 0x7c, 0xb3, 0x52, 0xdd, 0x66, 0x6d, 0x1f, 0x58, - 0xf2, 0xcb, 0x94, 0x4a, 0x8e, 0xe5, 0x6d, 0x3c, 0x86, 0xb3, 0xf2, 0x88, 0x88, 0xe2, 0x02, 0xc9, - 0x42, 0x36, 0xc8, 0xfb, 0xb1, 0xfe, 0x14, 0x07, 0x39, 0x71, 0xbe, 0x60, 0x39, 0xb9, 0x06, 0xc5, - 0x4a, 0xbd, 0xc6, 0x33, 0xf1, 0x2b, 0x21, 0xa4, 0xec, 0xae, 0xc3, 0x4f, 0x0a, 0x2d, 0x48, 0x83, - 0x40, 0xc4, 0x2c, 0x50, 0x71, 0xa7, 0x91, 0xd7, 0xb2, 0xbc, 0xe0, 0x78, 0xee, 0x32, 0x0e, 0xd6, - 0x1d, 0xe0, 0xa4, 0x6a, 0x37, 0x9f, 0xa9, 0xda, 0x95, 0xba, 0xc1, 0x42, 0xa6, 0x6e, 0xb0, 0x0a, - 0x33, 0x8d, 0xde, 0xb6, 0xac, 0x3b, 0x19, 0xc3, 0x23, 0xe8, 0x6d, 0x67, 0x75, 0x65, 0x92, 0xc4, - 0xf8, 0xb1, 0x3c, 0x94, 0xea, 0xed, 0xde, 0xae, 0xe3, 0x56, 0xed, 0xd0, 0x7e, 0x6a, 0xb5, 0xcd, - 0x6f, 0x68, 0xda, 0xe6, 0xc8, 0xd9, 0x33, 0x6a, 0xd8, 0x50, 0xaa, 0xe6, 0x9f, 0xcd, 0xc1, 0x4c, - 0x4c, 0xc2, 0x4f, 0xf8, 0x5b, 0x30, 0xc2, 0x7e, 0x08, 0x75, 0xc6, 0xf9, 0x14, 0x63, 0xc4, 0xba, - 0x1c, 0xfd, 0x25, 0xf4, 0xbf, 0x7a, 0x1a, 0x7a, 0xe4, 0xb0, 0xf8, 0x39, 0x98, 0x88, 0xd9, 0xa6, - 0x05, 0x87, 0x79, 0x55, 0x70, 0x98, 0x50, 0x93, 0x22, 0xfe, 0x46, 0x0e, 0xca, 0xc9, 0x96, 0x90, - 0x3b, 0x30, 0xce, 0x38, 0x39, 0x54, 0x6a, 0x5a, 0x5e, 0xec, 0xd3, 0xe6, 0xcb, 0x02, 0x8d, 0x7f, - 0x1e, 0x76, 0x3e, 0xe5, 0x10, 0x53, 0x72, 0x58, 0x34, 0xa1, 0xa4, 0x62, 0x65, 0x7c, 0xdd, 0xab, - 0xba, 0x58, 0x73, 0x3a, 0xbb, 0x1f, 0xd4, 0xaf, 0xfe, 0x5b, 0xda, 0x57, 0x0b, 0x89, 0xe5, 0x82, - 0x36, 0xb9, 0x32, 0x97, 0x22, 0x4e, 0x1a, 0xcc, 0xce, 0x28, 0xf6, 0x8d, 0xbc, 0x1a, 0x16, 0x34, - 0x35, 0xa1, 0x23, 0x3c, 0xf2, 0x2a, 0x8c, 0xf1, 0xfa, 0xd4, 0x9c, 0xf4, 0x5d, 0x84, 0xa8, 0x37, - 0x1f, 0x8e, 0x63, 0xfc, 0xed, 0x02, 0x9c, 0x8e, 0x3f, 0x6f, 0xab, 0xdb, 0xb2, 0x43, 0x5a, 0xb7, - 0x7d, 0xbb, 0x13, 0x1c, 0xb3, 0x02, 0x2e, 0xa6, 0x3e, 0x4d, 0x44, 0x87, 0xe0, 0x30, 0xe5, 0x83, - 0x8c, 0xc4, 0x07, 0xa1, 0x56, 0x9b, 0x7f, 0x90, 0xfc, 0x0c, 0x72, 0x07, 0x0a, 0x0d, 0x1a, 0x8a, - 0x0d, 0xfb, 0x42, 0xaa, 0x57, 0xd5, 0xef, 0xba, 0xdc, 0xa0, 0x21, 0x1f, 0x44, 0x1e, 0x70, 0x55, - 0x8b, 0xc3, 0xc0, 0xb8, 0x90, 0x07, 0x30, 0xb6, 0xf6, 0xb8, 0x4b, 0x9b, 0x21, 0x66, 0xd9, 0x52, - 0x02, 0x12, 0x64, 0xf3, 0xe3, 0xb8, 0x9c, 0xe5, 0xbc, 0xb8, 0x4a, 0xe8, 0xa9, 0x2f, 0x05, 0xbb, - 0xc5, 0xeb, 0x50, 0x94, 0x95, 0x9f, 0x64, 0xe6, 0x2e, 0xbe, 0x01, 0x93, 0x4a, 0x25, 0x27, 0x9a, - 0xf4, 0xbf, 0xc0, 0xf6, 0x55, 0xaf, 0x4d, 0xc5, 0xc4, 0x59, 0x4b, 0x09, 0x98, 0x4a, 0x42, 0x6d, - 0x2e, 0x60, 0x5a, 0xfb, 0xa2, 0x68, 0x80, 0xa4, 0x59, 0x83, 0x99, 0xc6, 0xbe, 0xd3, 0x8d, 0x93, - 0xb2, 0x68, 0xc7, 0x38, 0x26, 0xed, 0x15, 0xaa, 0x98, 0xe4, 0x31, 0x9e, 0xa4, 0x33, 0xfe, 0x43, - 0x0e, 0xc6, 0xd8, 0x5f, 0xf7, 0xaf, 0x3f, 0xa5, 0x5b, 0xe6, 0x35, 0x6d, 0xcb, 0x9c, 0x55, 0x92, - 0xac, 0xe1, 0xc6, 0x71, 0xfd, 0x98, 0xcd, 0xf2, 0x50, 0x0c, 0x10, 0x47, 0x26, 0x37, 0x61, 0x5c, - 0x98, 0xf8, 0x09, 0x6f, 0x0c, 0x35, 0x6b, 0x9b, 0x34, 0xfe, 0x8b, 0x74, 0x36, 0x5e, 0x37, 0xa9, - 0xe4, 0x92, 0xd4, 0xec, 0x32, 0x20, 0xd3, 0xe3, 0xa8, 0x39, 0x63, 0x19, 0x9b, 0x55, 0xcf, 0xe5, - 0x39, 0xc7, 0x82, 0x95, 0x33, 0x82, 0x53, 0xbf, 0x78, 0x4b, 0x15, 0xf1, 0x28, 0x57, 0x18, 0xc4, - 0xe4, 0xb4, 0x60, 0x92, 0xfd, 0x5e, 0xd7, 0x81, 0xd3, 0x8d, 0xc6, 0x2d, 0x34, 0x07, 0xae, 0x7b, - 0x7e, 0x78, 0xc3, 0xf3, 0x1f, 0x89, 0xb0, 0x32, 0x0d, 0xdd, 0x14, 0x26, 0xcb, 0x48, 0xf3, 0xe5, - 0x4c, 0x23, 0xcd, 0x01, 0xe6, 0x32, 0x86, 0x0b, 0x67, 0x1a, 0x8d, 0x5b, 0x3c, 0xe3, 0xd7, 0x9f, - 0x45, 0x7d, 0xbf, 0x91, 0x83, 0xd9, 0x46, 0xe3, 0x56, 0xa2, 0xaa, 0x75, 0x99, 0x6a, 0x2c, 0xa7, - 0xbd, 0xc7, 0x67, 0x77, 0x04, 0x8e, 0x42, 0x8e, 0x8b, 0x85, 0x4d, 0x2d, 0x60, 0x3c, 0x67, 0x42, - 0xea, 0x51, 0x72, 0xb3, 0xbc, 0xe6, 0xa1, 0xd3, 0xa7, 0xa1, 0xf8, 0x66, 0x21, 0xfc, 0x5b, 0x59, - 0xa9, 0xfe, 0x66, 0xc1, 0x20, 0xc6, 0xef, 0x9c, 0xe6, 0xe9, 0xd3, 0xe4, 0x6c, 0x79, 0x07, 0x4a, - 0x82, 0x1e, 0xdd, 0x58, 0x84, 0x69, 0xd2, 0x59, 0xb6, 0x41, 0xee, 0x70, 0x38, 0xcf, 0x84, 0xf3, - 0xbd, 0xc3, 0xa5, 0x11, 0xd6, 0x35, 0xa6, 0x86, 0x4e, 0xee, 0xc1, 0xd4, 0x86, 0xfd, 0x58, 0x51, - 0x50, 0x71, 0x27, 0xc5, 0x4b, 0x6c, 0x57, 0xe9, 0xd8, 0x8f, 0x87, 0x30, 0x82, 0xd5, 0xe9, 0xc9, - 0x3e, 0x4c, 0xeb, 0x6d, 0x12, 0x33, 0x30, 0x3d, 0x62, 0x57, 0x33, 0x47, 0xec, 0x6c, 0xd7, 0xf3, - 0x43, 0x6b, 0x27, 0x22, 0xd7, 0x52, 0x05, 0x26, 0x58, 0x93, 0x77, 0x60, 0x56, 0x09, 0xcb, 0x7f, - 0xc3, 0xf3, 0x3b, 0xb6, 0xbc, 0xa5, 0xe1, 0xab, 0x0d, 0x5a, 0xc7, 0xed, 0x20, 0xd8, 0x4c, 0x63, - 0x92, 0x2f, 0x65, 0x39, 0x7e, 0x8e, 0xc6, 0x96, 0xc0, 0x19, 0x8e, 0x9f, 0xfd, 0x2c, 0x81, 0xd3, - 0x2e, 0xa0, 0xbb, 0x83, 0x3c, 0x05, 0x8a, 0xbc, 0xf5, 0x43, 0x79, 0x02, 0x44, 0x23, 0xd7, 0xc7, - 0x23, 0x60, 0x19, 0x0a, 0x2b, 0xf5, 0x1b, 0xf8, 0xd6, 0x28, 0xcd, 0x02, 0xdd, 0x3d, 0xdb, 0x6d, - 0xe2, 0xed, 0x49, 0xf8, 0xe7, 0xa8, 0x07, 0xe5, 0x4a, 0xfd, 0x06, 0xb1, 0x61, 0x0e, 0x53, 0xd5, - 0x87, 0x1f, 0x5c, 0xbd, 0xaa, 0x0c, 0x55, 0x11, 0x3f, 0xed, 0x8a, 0xf8, 0xb4, 0x25, 0x4c, 0x74, - 0x1f, 0x5a, 0x8f, 0xaf, 0x5e, 0xcd, 0x1c, 0x90, 0xe8, 0xc3, 0xb2, 0x78, 0xb1, 0x03, 0x6b, 0xc3, - 0x7e, 0x1c, 0xbb, 0x55, 0x05, 0xc2, 0x85, 0xfe, 0x9c, 0x9c, 0x5a, 0xb1, 0x4b, 0x96, 0x76, 0x60, - 0xe9, 0x44, 0xec, 0xf2, 0x1b, 0x4f, 0xb0, 0x40, 0x38, 0x1f, 0x2e, 0x4a, 0x05, 0xac, 0x8c, 0xb3, - 0xa0, 0xde, 0xe0, 0x14, 0x74, 0xb2, 0x15, 0x5d, 0xe1, 0xf9, 0x15, 0x18, 0xed, 0xf5, 0x27, 0x56, - 0xae, 0xa8, 0x57, 0x78, 0xae, 0xf6, 0xd4, 0x9a, 0x35, 0x13, 0xe9, 0x7d, 0xb8, 0x9f, 0x99, 0xa9, - 0x73, 0x49, 0x6b, 0x06, 0x4a, 0x27, 0xd7, 0x0c, 0x50, 0x18, 0x59, 0xf7, 0x9a, 0xfb, 0x22, 0xea, - 0xf5, 0xfb, 0x6c, 0x17, 0x6e, 0x7b, 0xcd, 0xfd, 0x27, 0xe7, 0x01, 0x81, 0xec, 0xc9, 0x5d, 0x1e, - 0x44, 0xc8, 0x6f, 0x89, 0x3e, 0x11, 0x56, 0xf5, 0xf3, 0xd1, 0xd5, 0x58, 0x29, 0x8b, 0x43, 0x0b, - 0xf9, 0x2d, 0xd9, 0xb5, 0xa6, 0x4e, 0x4e, 0x28, 0x94, 0xab, 0x34, 0xd8, 0x0f, 0xbd, 0xee, 0x6a, - 0xdb, 0xe9, 0x62, 0x5c, 0x2e, 0x91, 0x36, 0x69, 0xe8, 0x3d, 0xb9, 0xc5, 0xe9, 0xad, 0xa6, 0x64, - 0x60, 0xa6, 0x58, 0x92, 0x2f, 0xc1, 0x34, 0x9b, 0xdc, 0x6b, 0x8f, 0x43, 0xea, 0xf2, 0x91, 0x9f, - 0x45, 0x89, 0x6e, 0x5e, 0x49, 0x3a, 0x1a, 0x15, 0xf2, 0x39, 0x85, 0x8b, 0x9d, 0x46, 0x04, 0x5a, - 0xc4, 0x70, 0x8d, 0x15, 0x69, 0xc1, 0xc2, 0x86, 0xfd, 0x38, 0xbe, 0x28, 0xab, 0x93, 0x94, 0xe0, - 0x04, 0xbb, 0x78, 0x74, 0xb8, 0xf4, 0x22, 0x9b, 0x60, 0x71, 0x26, 0xaf, 0x3e, 0xf3, 0xb5, 0x2f, - 0x27, 0xf2, 0x0d, 0x38, 0x23, 0x9a, 0x55, 0xc5, 0xec, 0xe9, 0x9e, 0x7f, 0xd0, 0xd8, 0xb3, 0xd1, - 0xa3, 0x72, 0xae, 0x4f, 0x87, 0x5d, 0xc9, 0xde, 0x12, 0x65, 0x87, 0xb5, 0x24, 0x1f, 0x2b, 0xe0, - 0x8c, 0xcc, 0x7e, 0x35, 0x90, 0x0f, 0x61, 0x9a, 0x3f, 0xb0, 0xca, 0xdc, 0xef, 0xe2, 0x69, 0x60, - 0x68, 0x37, 0x21, 0xfe, 0x6a, 0x1b, 0x27, 0x94, 0xd7, 0xba, 0x53, 0xe3, 0x4c, 0xde, 0x42, 0x4b, - 0x5c, 0x1e, 0xd3, 0xbf, 0x56, 0xc7, 0x87, 0x02, 0x71, 0x02, 0x75, 0x1d, 0xd7, 0x92, 0x6a, 0x96, - 0x6e, 0xb4, 0x5d, 0xa8, 0xd8, 0xe4, 0x01, 0x4c, 0x36, 0x1a, 0xb7, 0x6e, 0x38, 0x4c, 0x2e, 0xe9, - 0x4a, 0xbd, 0x7f, 0xfa, 0x2b, 0x5f, 0xc8, 0xfc, 0xca, 0xa9, 0x20, 0xd8, 0xb3, 0x30, 0xc1, 0x77, - 0xd3, 0xeb, 0x1e, 0x98, 0x2a, 0xa7, 0x0c, 0xd7, 0x99, 0x33, 0x4f, 0xd8, 0x75, 0xa6, 0x06, 0x33, - 0x8a, 0x39, 0x38, 0x5a, 0x17, 0x2d, 0xc4, 0x31, 0x4c, 0x55, 0x57, 0x99, 0xa4, 0xb3, 0x78, 0x92, - 0x4e, 0xfa, 0xcc, 0x9c, 0x3d, 0xa9, 0xcf, 0x8c, 0x03, 0xb3, 0x7c, 0x30, 0xc4, 0x3c, 0xc0, 0x91, - 0x5e, 0xec, 0xd3, 0x87, 0x97, 0x32, 0xfb, 0x70, 0x4e, 0x8c, 0xb4, 0x9c, 0x64, 0x68, 0x50, 0x90, - 0xe6, 0x4a, 0x76, 0x80, 0x08, 0xa0, 0x1d, 0xda, 0xdb, 0x76, 0x40, 0xb1, 0xae, 0x67, 0xfa, 0xd4, - 0xf5, 0x62, 0x66, 0x5d, 0xd3, 0xb2, 0xae, 0x6d, 0x5e, 0x4d, 0x06, 0x47, 0xe2, 0xca, 0x7a, 0xe4, - 0xfc, 0xc2, 0x8e, 0x7d, 0x56, 0x53, 0x8c, 0xa7, 0x11, 0x78, 0x38, 0xd0, 0xe4, 0xa4, 0x4d, 0xf6, - 0x7b, 0x06, 0x67, 0xf2, 0x18, 0x4e, 0xa7, 0xbf, 0x02, 0xeb, 0x3c, 0x87, 0x75, 0x9e, 0xd3, 0xea, - 0x4c, 0x22, 0xf1, 0x79, 0xa3, 0x37, 0x2b, 0x59, 0x6b, 0x1f, 0xfe, 0xe4, 0x47, 0x72, 0x70, 0x66, - 0xe3, 0x46, 0xe5, 0x3e, 0xf5, 0xb9, 0x58, 0xe2, 0x78, 0x6e, 0xe4, 0x64, 0xff, 0x9c, 0x78, 0x3c, - 0x49, 0xbe, 0x7f, 0x49, 0x89, 0x03, 0xb7, 0x0a, 0x26, 0xba, 0xbf, 0xd0, 0xd9, 0xb1, 0xad, 0x87, - 0x0a, 0x8b, 0x0c, 0x4f, 0xfc, 0x6f, 0xff, 0xd1, 0x52, 0xce, 0xec, 0x57, 0x15, 0x69, 0xc3, 0xa2, - 0xde, 0x2d, 0xd2, 0xab, 0x69, 0x8f, 0xb6, 0xdb, 0x0b, 0x4b, 0x38, 0xa3, 0x5f, 0x3d, 0x3a, 0x5c, - 0xba, 0x98, 0xea, 0xdd, 0xc8, 0x53, 0x8a, 0x61, 0x2a, 0x0d, 0x1e, 0xc0, 0x8f, 0x74, 0x32, 0x84, - 0xee, 0x85, 0xf3, 0x5a, 0x34, 0xae, 0x54, 0x79, 0x14, 0x2d, 0xee, 0x1c, 0x5b, 0xef, 0x7d, 0x05, - 0x44, 0x33, 0xcd, 0xf9, 0xf6, 0x48, 0x71, 0xaa, 0x3c, 0x9d, 0xe1, 0xee, 0x63, 0x7c, 0x27, 0x9f, - 0x38, 0x18, 0x49, 0x0d, 0xc6, 0xc5, 0x7c, 0xef, 0x7b, 0xc9, 0x38, 0x97, 0x39, 0xab, 0xc7, 0xc5, - 0xd2, 0x31, 0x25, 0x3d, 0x79, 0xc4, 0x58, 0x61, 0xa3, 0xc5, 0x8d, 0xf7, 0x2b, 0xfc, 0xdc, 0x43, - 0x90, 0x76, 0xc2, 0x57, 0x4f, 0xee, 0x1a, 0xab, 0x7b, 0x5e, 0xe3, 0x51, 0x2f, 0x6b, 0x23, 0xfb, - 0x3c, 0x07, 0x74, 0x21, 0xf2, 0xae, 0xd4, 0x13, 0x3e, 0x3f, 0xb1, 0x0a, 0x59, 0x2d, 0xc6, 0x6f, - 0xe5, 0x60, 0x4a, 0x3b, 0x59, 0xc9, 0x75, 0xc5, 0x79, 0x38, 0x7e, 0xea, 0xd4, 0x70, 0x70, 0xb3, - 0x4d, 0xba, 0x15, 0x5f, 0x57, 0xe2, 0x50, 0xf6, 0xa1, 0xc3, 0xc5, 0x96, 0xf4, 0x25, 0x1f, 0xac, - 0x1f, 0x5e, 0x82, 0x51, 0x1e, 0x88, 0x68, 0x24, 0xb6, 0x1d, 0x45, 0xfd, 0x8a, 0xc9, 0xe1, 0xc6, - 0x1f, 0x2f, 0xc1, 0xb4, 0x7e, 0x23, 0x26, 0xaf, 0xc2, 0x18, 0x2a, 0xf4, 0xa5, 0x7a, 0x05, 0xd5, - 0x42, 0xa8, 0xf3, 0xd7, 0xdc, 0xab, 0x38, 0x0e, 0x79, 0x09, 0x20, 0xf2, 0x43, 0x90, 0xcf, 0x59, - 0xa3, 0x47, 0x87, 0x4b, 0xb9, 0xd7, 0x4c, 0xa5, 0x80, 0x7c, 0x15, 0xe0, 0xae, 0xd7, 0xa2, 0x22, - 0xa5, 0x69, 0x61, 0x90, 0x3d, 0xcd, 0xcb, 0xa9, 0x94, 0xa6, 0xa7, 0x5c, 0xaf, 0x45, 0xd3, 0xf9, - 0x4b, 0x15, 0x8e, 0xe4, 0x4d, 0x18, 0x35, 0x7b, 0x6d, 0x2a, 0x9f, 0x3d, 0x26, 0xe5, 0x09, 0xd7, - 0x6b, 0xd3, 0x58, 0x4f, 0xe0, 0xf7, 0x92, 0xa6, 0xa2, 0x0c, 0x40, 0xde, 0xe3, 0xa9, 0x4e, 0x45, - 0xdc, 0xf8, 0xd1, 0xf8, 0x81, 0x4f, 0x91, 0x7c, 0x52, 0x91, 0xe3, 0x15, 0x12, 0x72, 0x0f, 0xc6, - 0xd5, 0x97, 0x29, 0x25, 0x0a, 0x85, 0xfa, 0x7a, 0xa9, 0x28, 0x1d, 0x44, 0x00, 0xdd, 0xe4, 0xa3, - 0x95, 0xe4, 0x42, 0xde, 0x86, 0x09, 0xc6, 0x9e, 0xed, 0x1c, 0x81, 0xb8, 0xd5, 0xe0, 0x33, 0x9e, - 0xf2, 0x41, 0x6c, 0xf7, 0xd1, 0xa2, 0xbb, 0x47, 0x04, 0xe4, 0x4b, 0x30, 0x51, 0xe9, 0x76, 0x45, - 0x57, 0x0f, 0xb4, 0xb3, 0xba, 0x90, 0xea, 0xea, 0x79, 0xbb, 0xdb, 0x4d, 0xf7, 0x74, 0xcc, 0x8f, - 0xec, 0x46, 0x41, 0x10, 0x87, 0x49, 0x4f, 0xfb, 0x4a, 0xaa, 0x82, 0x05, 0x19, 0xd7, 0x2f, 0x55, - 0x89, 0xce, 0x97, 0x74, 0xa1, 0x1c, 0x0b, 0x95, 0xa2, 0x2e, 0x18, 0x54, 0xd7, 0x6b, 0xa9, 0xba, - 0xd4, 0x01, 0x4c, 0x55, 0x97, 0xe2, 0x4e, 0x5a, 0x30, 0x2d, 0x0f, 0x28, 0x51, 0xdf, 0xe4, 0xa0, - 0xfa, 0x5e, 0x4a, 0xd5, 0x37, 0xd7, 0xda, 0x4e, 0xd7, 0x93, 0xe0, 0x49, 0xde, 0x86, 0x29, 0x09, - 0xc1, 0xf5, 0x81, 0xf6, 0x4d, 0x42, 0x21, 0xd8, 0xda, 0x46, 0xcf, 0x27, 0xad, 0x57, 0x34, 0x64, - 0x95, 0x9a, 0xcf, 0x8e, 0x29, 0x8d, 0x3a, 0x39, 0x2b, 0x74, 0x64, 0xf2, 0x45, 0x98, 0xac, 0x75, - 0x58, 0x43, 0x3c, 0xd7, 0x0e, 0xa9, 0xf0, 0x4f, 0x96, 0x36, 0x63, 0x4a, 0x89, 0x32, 0x55, 0xd1, - 0x5a, 0xc6, 0x89, 0x8b, 0xd4, 0x6b, 0xa6, 0x42, 0xc1, 0x3a, 0x8f, 0x3f, 0x45, 0x8a, 0x39, 0x2c, - 0x7d, 0x97, 0xcf, 0x65, 0xd8, 0x6d, 0x29, 0xec, 0x45, 0x8c, 0x70, 0x06, 0x95, 0x4f, 0x81, 0x89, - 0xfc, 0x0c, 0x2a, 0x4f, 0xf2, 0x0e, 0x4c, 0x8a, 0xcc, 0xdd, 0x15, 0xf3, 0x6e, 0xb0, 0x50, 0x8e, - 0xcd, 0xce, 0x65, 0x92, 0x6f, 0xcb, 0xf6, 0x13, 0x06, 0xca, 0x31, 0x3e, 0xf9, 0x00, 0xe6, 0x1f, - 0x38, 0x6e, 0xcb, 0x7b, 0x14, 0x88, 0x63, 0x4a, 0x6c, 0x74, 0xb3, 0xb1, 0x7b, 0xe4, 0x23, 0x5e, - 0x1e, 0xc9, 0x82, 0xa9, 0x8d, 0x2f, 0x93, 0x03, 0xf9, 0xa1, 0x14, 0x67, 0x3e, 0x83, 0xc8, 0xa0, - 0x19, 0xb4, 0x9c, 0x9a, 0x41, 0xe9, 0xea, 0x93, 0xd3, 0x29, 0xb3, 0x1a, 0xe2, 0x01, 0xd1, 0xcf, - 0xf7, 0xdb, 0x9e, 0xe3, 0x2e, 0xcc, 0xe1, 0x5e, 0xf8, 0x4c, 0x32, 0xca, 0x09, 0xe2, 0xd5, 0xbd, - 0xb6, 0xd3, 0x3c, 0xe0, 0x59, 0x7a, 0x92, 0x32, 0xff, 0x87, 0x9e, 0xf6, 0x5c, 0x92, 0xc1, 0x9a, - 0x7c, 0x11, 0x4a, 0xec, 0xff, 0x48, 0x29, 0x31, 0xaf, 0x59, 0xfa, 0x2a, 0x98, 0xa2, 0x1e, 0x1c, - 0x23, 0x4c, 0x2d, 0x9e, 0xa1, 0xaf, 0xd0, 0x58, 0x91, 0x37, 0x00, 0x98, 0xd8, 0x24, 0xb6, 0xe3, - 0x53, 0x71, 0x3a, 0x0c, 0x94, 0xba, 0xd2, 0x1b, 0x71, 0x8c, 0x4c, 0xde, 0x86, 0x49, 0xf6, 0xab, - 0xd1, 0x6b, 0x79, 0x6c, 0x6d, 0x9c, 0x46, 0x5a, 0xee, 0x2a, 0xce, 0x68, 0x03, 0x0e, 0xd7, 0x5c, - 0xc5, 0x63, 0x74, 0x72, 0x0b, 0x66, 0x30, 0x6d, 0x89, 0x08, 0x98, 0xef, 0xd0, 0x60, 0xe1, 0x8c, - 0x62, 0x42, 0x81, 0xe9, 0x75, 0x9d, 0xa8, 0x4c, 0xbd, 0xcb, 0x24, 0xc8, 0x48, 0x00, 0x73, 0xe9, - 0x37, 0xe8, 0x60, 0x61, 0x01, 0x3b, 0x49, 0x4a, 0xf0, 0x69, 0x0c, 0xbe, 0x1f, 0xb3, 0x11, 0x51, - 0x36, 0x2e, 0xf9, 0xa8, 0xa4, 0x56, 0x98, 0xc5, 0x9d, 0x98, 0x40, 0x6e, 0xae, 0xd6, 0x93, 0x79, - 0x3d, 0xce, 0x62, 0x0b, 0x70, 0x98, 0x77, 0x9b, 0x5d, 0x6b, 0x40, 0x6e, 0x8f, 0x0c, 0x6a, 0xf2, - 0x83, 0x70, 0x4a, 0xee, 0x20, 0xa2, 0x48, 0xcc, 0xeb, 0xc5, 0x13, 0xee, 0xc4, 0xad, 0xed, 0xa8, - 0xea, 0xd4, 0x94, 0xce, 0xae, 0x82, 0xd8, 0x30, 0x89, 0xc3, 0x2a, 0x6a, 0x7c, 0x66, 0x50, 0x8d, - 0x17, 0x53, 0x35, 0x9e, 0xc6, 0x89, 0x92, 0xae, 0x4c, 0xe5, 0x49, 0x56, 0x60, 0x4a, 0xac, 0x23, - 0x31, 0xdb, 0x9e, 0xc5, 0xde, 0x42, 0x25, 0x96, 0x5c, 0x81, 0xa9, 0x09, 0xa7, 0x93, 0xa8, 0x3b, - 0x32, 0x7f, 0x4c, 0x3a, 0xa7, 0xed, 0xc8, 0xc9, 0x37, 0x24, 0x1d, 0x99, 0xed, 0x48, 0xb1, 0x14, - 0xb3, 0xf6, 0xb8, 0xeb, 0x0b, 0x15, 0xd5, 0x73, 0x71, 0xa6, 0x52, 0x45, 0xf8, 0xb1, 0x68, 0x84, - 0xa1, 0x6e, 0x09, 0x59, 0x1c, 0xc8, 0x16, 0xcc, 0x45, 0xa7, 0xb6, 0xc2, 0x78, 0x29, 0xce, 0x1c, - 0x11, 0x1f, 0xf5, 0xd9, 0x7c, 0xb3, 0xe8, 0x89, 0x0d, 0x67, 0xb4, 0x73, 0x5a, 0x61, 0x7d, 0x1e, - 0x59, 0xbf, 0xcc, 0x6e, 0x64, 0xfa, 0x21, 0x9f, 0xcd, 0xbe, 0x1f, 0x1f, 0xf2, 0x21, 0x2c, 0x26, - 0xcf, 0x66, 0xa5, 0x96, 0xe7, 0xb1, 0x96, 0x57, 0x8e, 0x0e, 0x97, 0x2e, 0xa4, 0x8e, 0xf7, 0xec, - 0x8a, 0x06, 0x70, 0x23, 0x5f, 0x85, 0x05, 0xfd, 0x7c, 0x56, 0x6a, 0x32, 0xb0, 0x26, 0x5c, 0x3a, - 0xd1, 0xc1, 0x9e, 0x5d, 0x43, 0x5f, 0x1e, 0x24, 0x84, 0xa5, 0xcc, 0xd9, 0xad, 0x54, 0xf3, 0x42, - 0xdc, 0xa0, 0xd4, 0x2a, 0xc9, 0xae, 0xee, 0x38, 0x96, 0xe4, 0x11, 0x3c, 0x97, 0x75, 0x4c, 0x28, - 0x95, 0xbe, 0x18, 0x29, 0x81, 0x3f, 0x9d, 0x7d, 0xe4, 0x64, 0xd7, 0x7c, 0x0c, 0x5b, 0xf2, 0x25, - 0x38, 0xa5, 0xac, 0x2f, 0xa5, 0xbe, 0x97, 0xb0, 0x3e, 0x0c, 0x6e, 0xa0, 0x2e, 0xcc, 0xec, 0x5a, - 0xb2, 0x79, 0x90, 0x0e, 0xcc, 0xc9, 0x86, 0xa3, 0xb6, 0x5d, 0x1c, 0x3d, 0x17, 0xb4, 0x5d, 0x35, - 0x8d, 0xb1, 0x72, 0x5e, 0xec, 0xaa, 0x0b, 0xad, 0x6d, 0xab, 0x1b, 0x13, 0xaa, 0x33, 0x3d, 0x83, - 0x2f, 0xb9, 0x05, 0x63, 0x8d, 0x7a, 0xed, 0xc6, 0x8d, 0xb5, 0x85, 0x97, 0xb1, 0x06, 0xe9, 0xbe, - 0xc8, 0x81, 0xda, 0xa5, 0x49, 0xd8, 0x38, 0x76, 0x9d, 0x9d, 0x1d, 0xed, 0xc1, 0x8a, 0xa3, 0x92, - 0x1f, 0x42, 0xeb, 0x42, 0xb6, 0xa3, 0x56, 0x82, 0xc0, 0xd9, 0x75, 0x79, 0x4e, 0x8e, 0x57, 0xb4, - 0xf7, 0x7e, 0x99, 0xa5, 0x65, 0x15, 0x93, 0x08, 0xa7, 0xd0, 0xb9, 0xb4, 0xc9, 0xee, 0xff, 0x62, - 0xe7, 0xb6, 0xec, 0x98, 0x95, 0xba, 0x89, 0xa7, 0x2b, 0x62, 0xfd, 0xb6, 0xeb, 0x84, 0xd6, 0x5e, - 0x4f, 0x6b, 0xfe, 0xc2, 0xa7, 0xb5, 0x98, 0xe8, 0x3c, 0xb5, 0xb2, 0xd2, 0x6b, 0x2f, 0x8a, 0x0a, - 0x9f, 0xe5, 0xb7, 0xe5, 0x3e, 0x3d, 0x37, 0xbb, 0x9b, 0xa0, 0x0b, 0xc8, 0x5f, 0xcd, 0xc1, 0xe9, - 0x07, 0x9e, 0xbf, 0xdf, 0xf6, 0xec, 0x96, 0x6c, 0x95, 0xd8, 0xc3, 0x5f, 0x1d, 0xb4, 0x87, 0x7f, - 0x36, 0xb5, 0x87, 0x1b, 0x8f, 0x04, 0x1b, 0x2b, 0x4a, 0x72, 0x93, 0xda, 0xcf, 0xfb, 0x54, 0x45, - 0x7e, 0x08, 0xce, 0x67, 0x97, 0x28, 0x93, 0xf2, 0x35, 0x9c, 0x94, 0x57, 0x8f, 0x0e, 0x97, 0x5e, - 0xeb, 0x57, 0x53, 0xf6, 0x04, 0x3d, 0x96, 0x35, 0x79, 0x13, 0x0a, 0x1b, 0xab, 0xf5, 0x85, 0xcb, - 0xda, 0xd3, 0xf3, 0xc6, 0x6a, 0x5d, 0xe9, 0x28, 0xae, 0xd1, 0xec, 0x34, 0x35, 0x8d, 0xe6, 0xc6, - 0x6a, 0xfd, 0xf6, 0x48, 0xf1, 0x62, 0xf9, 0xd2, 0xed, 0x91, 0xe2, 0xa5, 0xf2, 0x2b, 0xe6, 0xb3, - 0x8d, 0xca, 0xc6, 0x7a, 0xad, 0x25, 0x0f, 0x66, 0x99, 0xc3, 0x87, 0xd7, 0x67, 0x5e, 0x18, 0x54, - 0x1a, 0x7f, 0x8d, 0xf1, 0x37, 0x72, 0xb0, 0x74, 0xcc, 0x04, 0x63, 0x67, 0x61, 0xfc, 0x71, 0x8d, - 0x28, 0x6f, 0x04, 0xf7, 0x8d, 0x8c, 0x0a, 0x2c, 0xdd, 0xe4, 0x44, 0x27, 0x41, 0xbf, 0x59, 0x91, - 0x7e, 0x4e, 0x71, 0x9f, 0x4e, 0xa7, 0x9d, 0x93, 0x58, 0xc6, 0x3a, 0x94, 0x93, 0x13, 0x8f, 0x7c, - 0x1e, 0xa6, 0xd4, 0xe4, 0x57, 0x52, 0x0d, 0xc1, 0x83, 0x06, 0xf9, 0xbb, 0xda, 0x61, 0xaa, 0x21, - 0x1a, 0x17, 0x60, 0x5a, 0xef, 0x62, 0x32, 0x0f, 0xa3, 0xa1, 0xe7, 0xb5, 0x05, 0x0f, 0x93, 0xff, - 0x30, 0x7e, 0x21, 0x07, 0x73, 0x19, 0xab, 0x98, 0x5c, 0x80, 0x11, 0x4c, 0x05, 0xac, 0x58, 0x26, - 0x25, 0x52, 0x00, 0x63, 0x39, 0xf9, 0x0c, 0x8c, 0x57, 0xef, 0x36, 0x1a, 0x95, 0xbb, 0x52, 0xe1, - 0xc1, 0x0f, 0x7b, 0x37, 0xb0, 0x02, 0x5b, 0x37, 0x68, 0x10, 0x68, 0xe4, 0x35, 0x18, 0xab, 0xd5, - 0x91, 0x40, 0xc9, 0xa0, 0xe3, 0x74, 0x93, 0xf8, 0x02, 0xc9, 0xf8, 0x56, 0x0e, 0x48, 0x7a, 0x4b, - 0x22, 0x57, 0x61, 0x52, 0xdd, 0xf8, 0x78, 0xbf, 0xe0, 0x2b, 0xaf, 0xb2, 0x38, 0x4d, 0x15, 0x87, - 0x54, 0x61, 0x14, 0x33, 0x6b, 0x46, 0x96, 0x14, 0x99, 0x4b, 0xef, 0x4c, 0x6a, 0xe9, 0x8d, 0x62, - 0xb6, 0x4e, 0x93, 0x13, 0x1b, 0x7f, 0x9a, 0x03, 0x92, 0x6d, 0x54, 0x39, 0x94, 0x25, 0xd7, 0xeb, - 0x4a, 0x98, 0x0e, 0xd5, 0xaa, 0x32, 0xca, 0xd4, 0xac, 0xaa, 0x1a, 0xe2, 0x80, 0x1e, 0x17, 0x34, - 0xd5, 0x56, 0x7f, 0xdf, 0xee, 0x4b, 0x30, 0x7a, 0x9f, 0xfa, 0xdb, 0xd2, 0xde, 0x1c, 0x6d, 0x54, - 0x1f, 0x32, 0x80, 0xaa, 0xea, 0x41, 0x0c, 0xcd, 0xbc, 0x73, 0x74, 0x58, 0xf3, 0xce, 0x3f, 0xce, - 0xc1, 0x7c, 0xd6, 0xe5, 0xe9, 0x18, 0xbf, 0x6d, 0x23, 0xe1, 0x72, 0x8e, 0xa6, 0x5f, 0xdc, 0xea, - 0x35, 0x72, 0x34, 0x5f, 0x82, 0x51, 0xd6, 0x43, 0x72, 0x5a, 0xa0, 0x7e, 0x8e, 0x75, 0x61, 0x60, - 0x72, 0x38, 0x43, 0x88, 0x13, 0x9f, 0x8c, 0x72, 0x04, 0x9e, 0xef, 0x84, 0xc3, 0x19, 0xc2, 0x86, - 0xd7, 0xa2, 0x52, 0x6f, 0x85, 0x08, 0x1d, 0x06, 0x30, 0x39, 0x9c, 0x5c, 0x80, 0xf1, 0x7b, 0xee, - 0x3a, 0xb5, 0x1f, 0xca, 0x04, 0x6b, 0x68, 0xaa, 0xe6, 0xb9, 0x56, 0x9b, 0xc1, 0x4c, 0x59, 0x68, - 0xfc, 0x6c, 0x0e, 0x66, 0x53, 0xf7, 0xb6, 0xe3, 0x5d, 0xd3, 0x07, 0xbb, 0x5b, 0x0e, 0xd3, 0x3e, - 0xfe, 0xf9, 0x23, 0xd9, 0x9f, 0x6f, 0xfc, 0xf7, 0x63, 0x70, 0xa6, 0x8f, 0x1a, 0x2d, 0x76, 0x07, - 0xcf, 0x1d, 0xeb, 0x0e, 0xfe, 0x65, 0x98, 0x5a, 0x6d, 0xdb, 0x4e, 0x27, 0xd8, 0xf4, 0xe2, 0x2f, - 0x8e, 0xbd, 0xca, 0xb0, 0x4c, 0x78, 0x75, 0x44, 0xee, 0x47, 0x67, 0x9b, 0x48, 0x61, 0x85, 0x5e, - 0x5a, 0x8a, 0xd7, 0x98, 0xa5, 0x1c, 0xb2, 0x0b, 0x7f, 0x4e, 0x1c, 0xb2, 0x75, 0x17, 0xc1, 0x91, - 0x27, 0xea, 0x22, 0x98, 0x6d, 0xc1, 0x3e, 0xfa, 0x71, 0xfc, 0x19, 0x56, 0x61, 0x8a, 0xdb, 0xea, - 0x55, 0x02, 0x3e, 0x48, 0x63, 0x29, 0xfb, 0x3e, 0x3b, 0x48, 0x8f, 0x85, 0x46, 0x43, 0x6e, 0xe9, - 0xee, 0x6c, 0xe3, 0xf8, 0x98, 0x7d, 0xa1, 0xbf, 0xbb, 0x9a, 0x1e, 0x13, 0x49, 0x75, 0x5b, 0xfb, - 0x06, 0xcc, 0x67, 0xdd, 0xc3, 0x17, 0x8a, 0x9a, 0x19, 0x70, 0x5f, 0x9b, 0xf3, 0xe1, 0x6f, 0xf3, - 0xfb, 0x99, 0xb7, 0x79, 0x19, 0x66, 0x60, 0xa2, 0xbf, 0x8f, 0x56, 0xbc, 0x16, 0x38, 0xee, 0xe0, - 0x60, 0x04, 0xc6, 0x97, 0x13, 0x71, 0x22, 0x92, 0xe4, 0xe4, 0x2d, 0x2d, 0x9c, 0xd7, 0xcb, 0xe9, - 0x70, 0x5e, 0xd9, 0xa1, 0x21, 0x78, 0xae, 0xac, 0x9f, 0xcd, 0xeb, 0xce, 0xed, 0x7f, 0x1e, 0x17, - 0xea, 0x25, 0x18, 0x7d, 0xb0, 0x47, 0x7d, 0x79, 0xa6, 0xe0, 0x87, 0x3c, 0x62, 0x00, 0xf5, 0x43, - 0x10, 0x83, 0xdc, 0x80, 0xe9, 0x3a, 0x9f, 0xb8, 0x72, 0x36, 0x8e, 0xc4, 0xca, 0xa0, 0xae, 0x50, - 0x59, 0x66, 0x4c, 0xc7, 0x04, 0x95, 0x71, 0x33, 0xd1, 0xe9, 0x22, 0x18, 0x19, 0xf7, 0xf3, 0xe2, - 0x52, 0xc7, 0x74, 0xec, 0x76, 0x18, 0x6f, 0xb6, 0x66, 0x02, 0x6a, 0xec, 0xc0, 0x73, 0x03, 0x19, - 0xb1, 0xc3, 0x1e, 0xba, 0xd1, 0xaf, 0x84, 0x49, 0xf8, 0x40, 0x52, 0x53, 0xa1, 0x33, 0xd6, 0x63, - 0x4f, 0xc4, 0x5a, 0x15, 0x5d, 0x21, 0xdf, 0x84, 0x92, 0xea, 0x2b, 0x22, 0x38, 0x67, 0xb8, 0x96, - 0x8c, 0xb0, 0x01, 0x31, 0x27, 0x25, 0x72, 0xad, 0x15, 0x18, 0xff, 0xb6, 0x00, 0x0b, 0xfd, 0x7c, - 0xf1, 0xc8, 0x4f, 0x45, 0x71, 0x5d, 0xd0, 0xd1, 0xcd, 0x8b, 0x55, 0x65, 0xbc, 0x8a, 0x37, 0x8f, - 0x71, 0xe6, 0xbb, 0x9c, 0x49, 0xcc, 0xad, 0x99, 0x23, 0x37, 0x17, 0x3c, 0xd8, 0x69, 0xcb, 0xda, - 0x3e, 0xb0, 0x14, 0xaf, 0x4f, 0x33, 0xbb, 0x62, 0xf2, 0x3e, 0x9c, 0x32, 0x69, 0xd3, 0xeb, 0x74, - 0xa8, 0xdb, 0x52, 0xbd, 0xf0, 0xc4, 0x21, 0x2e, 0x42, 0x9c, 0x44, 0x08, 0x3a, 0xcb, 0x4c, 0x4a, - 0x72, 0x17, 0x66, 0xe3, 0x18, 0x6a, 0x32, 0x11, 0x80, 0x92, 0x2f, 0x27, 0x8e, 0xf9, 0x26, 0xd3, - 0x00, 0xa8, 0x17, 0xac, 0x14, 0x29, 0xb9, 0x02, 0xb0, 0x6a, 0xbb, 0x75, 0xdf, 0x6b, 0x52, 0x11, - 0x86, 0xa0, 0x28, 0x6c, 0xfd, 0x6c, 0x8c, 0xbb, 0xc2, 0xc0, 0xa6, 0x82, 0xb2, 0x68, 0xc1, 0x62, - 0xff, 0x8e, 0xca, 0xb0, 0xc8, 0xfe, 0xb4, 0x6e, 0xe8, 0x7f, 0x2a, 0x35, 0xd0, 0x8c, 0x8f, 0x6a, - 0xa8, 0xfd, 0x0d, 0x28, 0xa9, 0x0b, 0x13, 0xa5, 0x16, 0xf6, 0x5b, 0x6c, 0x24, 0x5c, 0x6a, 0x61, - 0x00, 0x93, 0xc3, 0xe3, 0x77, 0xc9, 0x7c, 0xf6, 0xbb, 0x64, 0xbc, 0x63, 0x14, 0x8e, 0xdb, 0x31, - 0x58, 0xe5, 0x78, 0x28, 0x2a, 0x95, 0xe3, 0x6f, 0xb5, 0x72, 0x8c, 0x2a, 0x67, 0x72, 0xf8, 0x13, - 0xad, 0xfc, 0x9f, 0xc9, 0xf4, 0x9c, 0xe8, 0x79, 0xa8, 0xce, 0xde, 0xc8, 0xf3, 0x30, 0xbd, 0xe1, - 0xc7, 0x98, 0xb1, 0xec, 0x9a, 0x3f, 0x56, 0x76, 0x3d, 0xc1, 0xde, 0x85, 0xf7, 0x30, 0xbe, 0x0b, - 0x8c, 0xc4, 0xf7, 0x0d, 0x3b, 0x65, 0xb9, 0x25, 0xb1, 0x8c, 0x6f, 0xe7, 0xe0, 0x54, 0xe6, 0xfb, - 0x0f, 0xab, 0x95, 0x3f, 0x34, 0x29, 0x5b, 0x77, 0xf2, 0x95, 0x89, 0x63, 0x9c, 0x24, 0x3a, 0xcf, - 0xf0, 0x6d, 0x31, 0x9e, 0x87, 0x89, 0xc8, 0xfa, 0x80, 0xdd, 0xe7, 0xf8, 0xd0, 0xf1, 0xf0, 0xa3, - 0xe2, 0x11, 0xfb, 0x17, 0x72, 0x00, 0xec, 0x13, 0x3e, 0x41, 0x3f, 0x01, 0xde, 0x07, 0x7d, 0xfc, - 0x04, 0x92, 0xfd, 0x91, 0xa4, 0x33, 0xfe, 0x59, 0x1e, 0xc6, 0xd8, 0x5f, 0x4f, 0x6d, 0xd0, 0xf5, - 0x6c, 0x3f, 0x01, 0xd6, 0xa4, 0xfe, 0xa1, 0xd6, 0xc9, 0x1a, 0x8c, 0xf1, 0x34, 0x95, 0xe2, 0x55, - 0x7c, 0x4e, 0x25, 0x93, 0xf9, 0x2b, 0xa3, 0x10, 0x35, 0x01, 0x42, 0x34, 0xed, 0x19, 0x42, 0x14, - 0x77, 0x83, 0xdf, 0xcf, 0x41, 0x49, 0x25, 0x26, 0x5f, 0x84, 0x69, 0x19, 0x48, 0x9a, 0x87, 0x6d, - 0x12, 0x66, 0x17, 0xd2, 0x44, 0x52, 0x06, 0x92, 0x56, 0xc3, 0x3c, 0x69, 0xf8, 0xaa, 0xa4, 0xd0, - 0x55, 0x91, 0x49, 0x0b, 0x48, 0x67, 0xc7, 0xb6, 0x1e, 0x51, 0x7b, 0x9f, 0x06, 0xa1, 0xc5, 0x4d, - 0xd9, 0x84, 0x75, 0x86, 0x64, 0xbf, 0x71, 0xa3, 0xc2, 0xad, 0xd8, 0xd0, 0x79, 0x9d, 0x47, 0x04, - 0x4f, 0xd1, 0xa8, 0x4f, 0xce, 0x9d, 0x1d, 0xfb, 0x01, 0x2f, 0xe4, 0x74, 0xc6, 0x9f, 0x8c, 0xf1, - 0x99, 0x2b, 0x22, 0xcf, 0x6f, 0xc3, 0xf4, 0xbd, 0x5a, 0x75, 0x55, 0x79, 0x80, 0xd2, 0x13, 0x17, - 0xae, 0x3d, 0x0e, 0xa9, 0xef, 0xda, 0x6d, 0xa9, 0xcb, 0x89, 0x25, 0x20, 0xcf, 0x69, 0x35, 0xb3, - 0x1f, 0xa7, 0x12, 0x1c, 0x59, 0x1d, 0x5c, 0x6b, 0x14, 0xd5, 0x91, 0x1f, 0xb2, 0x8e, 0xc0, 0xee, - 0xb4, 0xfb, 0xd4, 0xa1, 0x73, 0x24, 0x7b, 0xa8, 0xd6, 0xd9, 0xeb, 0x6d, 0x2b, 0xb5, 0x14, 0x06, - 0xd7, 0xf2, 0x82, 0xa8, 0xe5, 0x19, 0xa1, 0x6e, 0xcc, 0xac, 0x27, 0xc5, 0x35, 0xde, 0x73, 0x46, - 0x8e, 0xdd, 0x73, 0xfe, 0x93, 0x1c, 0x8c, 0xf1, 0xdb, 0x93, 0x98, 0xc6, 0x7d, 0xee, 0x67, 0x0f, - 0x9e, 0xcc, 0xfd, 0xac, 0x8c, 0x67, 0x8e, 0x36, 0xa1, 0x79, 0x19, 0xa9, 0x26, 0xd6, 0x05, 0x89, - 0xa4, 0x9c, 0x5d, 0x47, 0x24, 0x76, 0x3d, 0x7e, 0x59, 0x90, 0x5a, 0x1c, 0x34, 0x68, 0xfc, 0xd8, - 0x48, 0x11, 0x32, 0xd0, 0xd2, 0xb8, 0x08, 0x1a, 0xa4, 0x87, 0x0a, 0x5a, 0x87, 0x09, 0x11, 0x8a, - 0x68, 0xe5, 0x40, 0x18, 0x8c, 0x94, 0x35, 0x93, 0xbf, 0xd6, 0xca, 0x41, 0x7c, 0x33, 0x14, 0xc1, - 0x8c, 0xac, 0x6d, 0xd5, 0x5d, 0x26, 0x66, 0x40, 0xee, 0xc1, 0x44, 0x1c, 0x99, 0x5f, 0x4f, 0xc6, - 0x13, 0xc1, 0x45, 0x64, 0x46, 0x19, 0xcf, 0x24, 0x23, 0x10, 0x7f, 0xcc, 0x83, 0xac, 0x43, 0x19, - 0xcd, 0x44, 0x69, 0x8b, 0xaf, 0x9a, 0x5a, 0x95, 0x87, 0xbb, 0x11, 0xe2, 0x53, 0xc8, 0xcb, 0xc4, - 0x72, 0x4b, 0x38, 0x33, 0xa7, 0x28, 0x8d, 0x9f, 0xc9, 0x43, 0x39, 0x39, 0xfb, 0xc8, 0xdb, 0x30, - 0x19, 0x65, 0x46, 0x88, 0xc2, 0x29, 0xe0, 0xc3, 0x71, 0x9c, 0x4a, 0x41, 0xcf, 0x64, 0xaf, 0xa0, - 0x93, 0x65, 0x28, 0xb2, 0x45, 0xec, 0xc6, 0x81, 0x6d, 0x71, 0xdb, 0xee, 0x09, 0x98, 0xaa, 0x54, - 0x92, 0x78, 0xa4, 0x01, 0x73, 0x6c, 0xd1, 0x34, 0x1c, 0x77, 0xb7, 0x4d, 0xd7, 0xbd, 0x5d, 0xaf, - 0x17, 0xc6, 0x89, 0xdd, 0xf9, 0xfd, 0xd9, 0xee, 0xb4, 0xb5, 0x62, 0x3d, 0xad, 0x7b, 0x06, 0x35, - 0x79, 0x8d, 0x1f, 0x33, 0xb5, 0xaa, 0xb0, 0xf7, 0xc2, 0x63, 0x1f, 0xed, 0x14, 0xb5, 0x8f, 0x17, - 0x48, 0xca, 0xce, 0xfa, 0x47, 0x79, 0x98, 0x54, 0xa6, 0x1f, 0xb9, 0x04, 0xc5, 0x5a, 0xb0, 0xee, - 0x35, 0xf7, 0xa3, 0x48, 0xbf, 0x53, 0x47, 0x87, 0x4b, 0x13, 0x4e, 0x60, 0xb5, 0x11, 0x68, 0x46, - 0xc5, 0x64, 0x05, 0xa6, 0xf8, 0x5f, 0x52, 0xb2, 0xcd, 0xc7, 0x7a, 0x63, 0x8e, 0x9c, 0x21, 0xd5, - 0xea, 0x24, 0xe4, 0x2b, 0x00, 0x1c, 0x80, 0x61, 0x56, 0x0a, 0xc3, 0x07, 0x88, 0x11, 0x15, 0x64, - 0x04, 0x58, 0x51, 0x18, 0x92, 0xaf, 0xf1, 0xc4, 0x0b, 0x72, 0xb9, 0x8c, 0x0c, 0x1f, 0xe1, 0x86, - 0xf1, 0xb7, 0xb2, 0x03, 0x6d, 0xa9, 0x2c, 0x45, 0x56, 0xba, 0x45, 0x99, 0x82, 0xb8, 0x12, 0x22, - 0xa2, 0x82, 0x61, 0xfc, 0xaf, 0x39, 0x65, 0x91, 0x91, 0xbb, 0x30, 0x11, 0x4d, 0x20, 0x61, 0x6a, - 0x19, 0xdd, 0x70, 0x25, 0xdc, 0xa4, 0x3b, 0x2b, 0xcf, 0x08, 0xab, 0xcf, 0xb9, 0x68, 0x1a, 0x6a, - 0x6b, 0x4e, 0x02, 0xc9, 0x17, 0x60, 0x04, 0xbb, 0x2e, 0x7f, 0x6c, 0xd3, 0xe4, 0x29, 0x3f, 0xc2, - 0xfa, 0x0c, 0x1b, 0x82, 0x94, 0xe4, 0x33, 0x22, 0x0a, 0x02, 0xef, 0xfc, 0x69, 0xe5, 0xa8, 0x66, - 0xdf, 0x11, 0x1d, 0xef, 0x71, 0xac, 0x35, 0x65, 0xf6, 0xfc, 0x8d, 0x3c, 0x94, 0x93, 0x4b, 0x9b, - 0xbc, 0x07, 0x25, 0x79, 0xfc, 0xde, 0xb2, 0x45, 0x7e, 0xa6, 0x92, 0xc8, 0x8f, 0x24, 0xcf, 0xe0, - 0x3d, 0x5b, 0x35, 0xcd, 0x34, 0x35, 0x02, 0x26, 0x0b, 0x6d, 0x8a, 0x80, 0xad, 0xca, 0xa2, 0x0a, - 0xbd, 0xb0, 0x9b, 0x88, 0xf7, 0x2f, 0xd1, 0xc8, 0xeb, 0x50, 0xd8, 0xb8, 0x51, 0x11, 0x8e, 0xaf, - 0xe5, 0xe4, 0x21, 0x2d, 0xde, 0x5b, 0x34, 0x7b, 0x76, 0x86, 0x4f, 0xd6, 0x95, 0xd4, 0x18, 0x63, - 0x9a, 0x19, 0xae, 0x04, 0x47, 0x8d, 0x3b, 0x3e, 0x47, 0xc6, 0xed, 0x91, 0x62, 0xa1, 0x3c, 0x22, - 0xc2, 0xa5, 0xff, 0xcb, 0x02, 0x4c, 0x44, 0xf5, 0x13, 0xa2, 0xc6, 0x20, 0x10, 0xf1, 0x06, 0xce, - 0x42, 0x51, 0x4a, 0x77, 0xc2, 0xff, 0x75, 0x3c, 0x10, 0x92, 0xdd, 0x02, 0x48, 0x31, 0x8e, 0xef, - 0x0a, 0xa6, 0xfc, 0x49, 0xae, 0x42, 0x24, 0xa3, 0xf5, 0x13, 0xe6, 0xf8, 0x4d, 0x3c, 0x42, 0x23, - 0xd3, 0x90, 0x77, 0x78, 0x08, 0xca, 0x09, 0x33, 0xef, 0xb4, 0xc8, 0x7b, 0x50, 0xb4, 0x5b, 0x78, - 0x7f, 0x1d, 0x26, 0x55, 0x75, 0x91, 0x71, 0xe3, 0x67, 0x06, 0x52, 0x55, 0x42, 0x52, 0x81, 0x09, - 0x1e, 0xd3, 0x3f, 0xa0, 0xad, 0x21, 0x0e, 0xa0, 0x98, 0x03, 0xa6, 0x02, 0xd8, 0x0a, 0x68, 0x8b, - 0xbc, 0x0c, 0x23, 0x6c, 0x34, 0xc5, 0x89, 0x23, 0x85, 0x4a, 0x36, 0x98, 0xbc, 0xc3, 0x6e, 0x7d, - 0xca, 0x44, 0x04, 0xf2, 0x22, 0x14, 0x7a, 0xcb, 0x3b, 0xe2, 0x2c, 0x29, 0xc7, 0x69, 0x6a, 0x22, - 0x34, 0x56, 0x4c, 0xae, 0x41, 0xf1, 0x91, 0x9e, 0xe1, 0xe4, 0x54, 0x62, 0x18, 0x23, 0xfc, 0x08, - 0x91, 0xbc, 0x0c, 0x85, 0x20, 0xf0, 0x84, 0xa1, 0xdf, 0x5c, 0x64, 0x7d, 0x7d, 0x2f, 0x1a, 0x35, - 0xc6, 0x3d, 0x08, 0xbc, 0x95, 0x22, 0x8c, 0xf1, 0x03, 0xc6, 0x78, 0x0e, 0x20, 0xfe, 0xc6, 0xf4, - 0xed, 0xd9, 0xf8, 0x0a, 0x4c, 0x44, 0xdf, 0x46, 0xce, 0x01, 0xec, 0xd3, 0x03, 0x6b, 0xcf, 0x76, - 0x5b, 0x6d, 0x2e, 0x9d, 0x96, 0xcc, 0x89, 0x7d, 0x7a, 0x70, 0x0b, 0x01, 0xe4, 0x0c, 0x8c, 0x77, - 0xd9, 0xf0, 0x8b, 0x39, 0x5e, 0x32, 0xc7, 0xba, 0xbd, 0x6d, 0x36, 0x95, 0x17, 0x60, 0x1c, 0xd5, - 0xfc, 0x62, 0x45, 0x4e, 0x99, 0xf2, 0xa7, 0xf1, 0xef, 0x0b, 0x98, 0x08, 0x50, 0x69, 0x10, 0x79, - 0x01, 0xa6, 0x9a, 0x3e, 0xc5, 0xb3, 0xcc, 0x66, 0x12, 0x9a, 0xa8, 0xa7, 0x14, 0x03, 0x6b, 0x2d, - 0x72, 0x01, 0x66, 0xe2, 0x9c, 0xed, 0x56, 0x73, 0x5b, 0x64, 0x2e, 0x2a, 0x99, 0x53, 0x5d, 0x99, - 0xb9, 0x7d, 0x75, 0x1b, 0x63, 0xac, 0x96, 0xd5, 0x14, 0x01, 0xac, 0x47, 0xc4, 0xfc, 0x9b, 0x51, - 0xe0, 0x68, 0xb3, 0x7c, 0x1a, 0xc6, 0x6c, 0x7b, 0xb7, 0xe7, 0x70, 0x25, 0x44, 0xc9, 0x14, 0xbf, - 0xc8, 0xa7, 0x61, 0x36, 0xce, 0xb9, 0x21, 0x9b, 0x31, 0x8a, 0xcd, 0x28, 0x47, 0x05, 0xab, 0x1c, - 0x4e, 0x5e, 0x03, 0xa2, 0xd6, 0xe7, 0x6d, 0x7f, 0x48, 0x9b, 0x7c, 0x4e, 0x96, 0xcc, 0x59, 0xa5, - 0xe4, 0x1e, 0x16, 0x90, 0xe7, 0x51, 0x17, 0x85, 0xd2, 0x21, 0x76, 0x1b, 0xe6, 0xc9, 0x45, 0x95, - 0x13, 0xc2, 0x58, 0xdf, 0x5d, 0x84, 0xb2, 0xd2, 0x1d, 0x98, 0x85, 0x81, 0x27, 0xed, 0x31, 0xa7, - 0x63, 0xb8, 0xd9, 0xad, 0xb5, 0xc8, 0x07, 0xb0, 0xa8, 0x60, 0xf2, 0x94, 0xbd, 0x16, 0x6d, 0x3b, - 0xbb, 0xce, 0x76, 0x9b, 0x8a, 0xf9, 0x96, 0x9e, 0xd5, 0xd1, 0x75, 0xd4, 0x5c, 0x88, 0xa9, 0x79, - 0x32, 0xdf, 0x35, 0x41, 0x4b, 0xd6, 0x61, 0x3e, 0xc1, 0x99, 0xb6, 0xac, 0x5e, 0xb7, 0x6f, 0xf0, - 0xd1, 0x98, 0x27, 0xd1, 0x79, 0xd2, 0xd6, 0x56, 0xd7, 0xf8, 0x06, 0x94, 0xd4, 0x39, 0xc9, 0x3a, - 0x41, 0x95, 0x4b, 0xc4, 0xec, 0x9b, 0x8c, 0x60, 0x35, 0x76, 0x2f, 0x9c, 0x8e, 0x51, 0x70, 0x10, - 0xf9, 0xf6, 0x32, 0x15, 0x41, 0x71, 0x08, 0x9f, 0x87, 0x52, 0xcb, 0x09, 0xba, 0x6d, 0xfb, 0x00, - 0x2d, 0x4f, 0xc5, 0x48, 0x4f, 0x0a, 0x18, 0xea, 0x1d, 0x57, 0x60, 0x36, 0xb5, 0x0f, 0x2a, 0x92, - 0x06, 0xdf, 0xd7, 0x07, 0x4b, 0x1a, 0x86, 0x0b, 0x25, 0xf5, 0x5c, 0x3b, 0x26, 0xc5, 0xd6, 0x69, - 0x8c, 0x69, 0xc5, 0x37, 0xfd, 0xb1, 0xa3, 0xc3, 0xa5, 0xbc, 0xd3, 0xc2, 0x48, 0x56, 0x17, 0xa1, - 0x28, 0x25, 0x36, 0x21, 0x28, 0xe1, 0x5b, 0x96, 0x7c, 0xb2, 0x37, 0xa3, 0x52, 0xe3, 0x65, 0x18, - 0x17, 0x47, 0xd7, 0xe0, 0x17, 0x2c, 0xe3, 0x9b, 0x79, 0x98, 0x31, 0x29, 0xdb, 0x58, 0x29, 0xcf, - 0xab, 0xf7, 0xd4, 0x5e, 0xd1, 0xb3, 0x63, 0x6d, 0x6b, 0x6d, 0x1b, 0x90, 0xd1, 0xee, 0x57, 0x73, - 0x30, 0x97, 0x81, 0xfb, 0x91, 0x32, 0xba, 0x5f, 0x87, 0x89, 0xaa, 0x63, 0xb7, 0x2b, 0xad, 0x56, - 0x14, 0xe0, 0x0a, 0xe5, 0x7c, 0x4c, 0xfb, 0x68, 0x33, 0xa8, 0x2a, 0xc4, 0x44, 0xa8, 0xe4, 0x15, - 0x31, 0x29, 0x0a, 0x51, 0xb7, 0xe2, 0xa4, 0xf8, 0xde, 0xe1, 0x12, 0xf0, 0x6f, 0xda, 0x8c, 0xa6, - 0x08, 0xc6, 0xbf, 0xe7, 0xc0, 0xd8, 0xdf, 0xf0, 0xa9, 0x1d, 0xba, 0xec, 0xf8, 0xf7, 0xc9, 0xe6, - 0x0d, 0x95, 0xd4, 0xee, 0x27, 0xf2, 0x70, 0x3a, 0x9b, 0xf0, 0xa3, 0x26, 0xe7, 0xc7, 0x74, 0x82, - 0x4a, 0xce, 0x0e, 0x4c, 0xce, 0xcf, 0x73, 0x0f, 0x22, 0x7e, 0x8c, 0x40, 0x76, 0x60, 0x6a, 0xdd, - 0x0e, 0xc2, 0x5b, 0xd4, 0xf6, 0xc3, 0x6d, 0x6a, 0x87, 0x43, 0x48, 0xf2, 0xd2, 0xca, 0x68, 0x01, - 0x85, 0x89, 0x3d, 0x49, 0x99, 0x90, 0xb5, 0x75, 0xb6, 0xd1, 0x44, 0x19, 0x19, 0x62, 0xa2, 0x7c, - 0x1d, 0x66, 0x1a, 0xb4, 0x63, 0x77, 0xf7, 0x3c, 0x5f, 0xc6, 0x11, 0xb9, 0x0c, 0x53, 0x11, 0x28, - 0x73, 0xb6, 0xe8, 0xc5, 0x1a, 0xbe, 0xd2, 0x11, 0xf1, 0x56, 0xa2, 0x17, 0x1b, 0x7f, 0x33, 0x0f, - 0x67, 0x2a, 0x4d, 0x61, 0x32, 0x2d, 0x0a, 0xa4, 0x67, 0xc7, 0x27, 0x5c, 0x37, 0xb9, 0x02, 0x13, - 0x1b, 0xf6, 0xe3, 0x75, 0x6a, 0x07, 0x34, 0x10, 0x09, 0x61, 0xb8, 0xd8, 0x6b, 0x3f, 0x8e, 0xdf, - 0x1e, 0xcd, 0x18, 0x47, 0x55, 0x23, 0x8c, 0x7c, 0x4c, 0x35, 0x82, 0x01, 0x63, 0xb7, 0xbc, 0x76, - 0x4b, 0x9c, 0xf5, 0xc2, 0xe0, 0x61, 0x0f, 0x21, 0xa6, 0x28, 0x31, 0xfe, 0x38, 0x07, 0xd3, 0xd1, - 0x17, 0xe3, 0x27, 0x7c, 0xe2, 0x5d, 0x72, 0x01, 0xc6, 0xb1, 0xa2, 0x5a, 0x55, 0x3d, 0x34, 0xda, - 0x14, 0x13, 0xdc, 0xb6, 0x4c, 0x59, 0xa8, 0xf6, 0xc4, 0xe8, 0xc7, 0xeb, 0x09, 0xe3, 0xef, 0xa1, - 0x2d, 0x85, 0xda, 0x4a, 0x76, 0x12, 0x29, 0x1f, 0x92, 0x1b, 0xf2, 0x43, 0xf2, 0x4f, 0x6c, 0x48, - 0x0a, 0x7d, 0x87, 0xe4, 0x47, 0xf3, 0x30, 0x19, 0x7d, 0xec, 0xf7, 0x59, 0xe2, 0x98, 0xa8, 0x5d, - 0x43, 0xc5, 0xfe, 0x6a, 0x28, 0x7b, 0x85, 0x08, 0xb1, 0xf5, 0x05, 0x18, 0x13, 0x8b, 0x29, 0x97, - 0xf0, 0x70, 0x48, 0x8c, 0xee, 0xca, 0xb4, 0x60, 0x3d, 0x86, 0x03, 0x1a, 0x98, 0x82, 0x0e, 0x83, - 0xab, 0x3d, 0xa0, 0xdb, 0xc2, 0xb4, 0xe6, 0xa9, 0x3d, 0xa3, 0xb2, 0x83, 0xab, 0xc5, 0x0d, 0x1b, - 0xea, 0x74, 0xfa, 0x1f, 0x8b, 0x50, 0x4e, 0x92, 0x1c, 0x9f, 0x9a, 0xa7, 0xde, 0xdb, 0xe6, 0x57, - 0x15, 0x9e, 0x9a, 0xa7, 0xdb, 0xdb, 0x36, 0x19, 0x0c, 0xcd, 0xf5, 0x7c, 0xe7, 0x21, 0xb6, 0xba, - 0x24, 0xcc, 0xf5, 0x7c, 0xe7, 0xa1, 0x66, 0xae, 0xe7, 0x3b, 0x0f, 0x51, 0x91, 0xb0, 0xde, 0xc0, - 0xc0, 0x23, 0x78, 0x4f, 0x11, 0x8a, 0x84, 0x76, 0x90, 0xcc, 0x37, 0x2a, 0xd1, 0xd8, 0x51, 0xb9, - 0x42, 0x6d, 0x5f, 0xa4, 0x91, 0x11, 0xdb, 0x19, 0x1e, 0x95, 0xdb, 0x08, 0xb6, 0x42, 0x06, 0x37, - 0x55, 0x24, 0xd2, 0x06, 0xa2, 0xfc, 0x94, 0x0b, 0xf8, 0xf8, 0xbb, 0xb5, 0xb4, 0x4e, 0x9e, 0x57, - 0x59, 0x5b, 0xea, 0x6a, 0xce, 0xe0, 0xfb, 0x24, 0xb5, 0xbf, 0x75, 0x11, 0x66, 0x1a, 0x15, 0x48, - 0xc5, 0x63, 0x99, 0xc9, 0x80, 0x49, 0xc0, 0xc3, 0x50, 0x47, 0x6a, 0xa4, 0x98, 0x09, 0x79, 0x17, - 0x26, 0xd5, 0x70, 0x32, 0x3c, 0xe8, 0xc9, 0xb3, 0x3c, 0x38, 0x6d, 0x9f, 0x1c, 0xf5, 0x2a, 0x01, - 0xd9, 0x86, 0x33, 0xab, 0x9e, 0x1b, 0xf4, 0x3a, 0xf2, 0x19, 0x3d, 0xce, 0x8c, 0x00, 0x38, 0x14, - 0x18, 0x9b, 0xa2, 0x29, 0x50, 0xe4, 0x13, 0xbc, 0x8c, 0x3a, 0xa2, 0x5d, 0x40, 0xfa, 0x31, 0x22, - 0x9b, 0x30, 0x89, 0x1a, 0x54, 0x61, 0x0a, 0x3c, 0xa9, 0x6f, 0x1b, 0x71, 0x49, 0x95, 0x2d, 0x0c, - 0x1e, 0x4d, 0xd1, 0xee, 0xb4, 0xa5, 0xf7, 0x92, 0xaa, 0x09, 0x56, 0x90, 0xc9, 0x57, 0x60, 0x9a, - 0x5f, 0xd1, 0x1e, 0xd0, 0x6d, 0x3e, 0x77, 0x4a, 0x9a, 0x26, 0x42, 0x2f, 0xe4, 0xb6, 0x24, 0x42, - 0x6f, 0xfd, 0x88, 0x6e, 0xf3, 0xb1, 0xd7, 0x7c, 0x07, 0x35, 0x7c, 0xb2, 0x05, 0x73, 0xb7, 0xec, - 0x80, 0x03, 0x95, 0xb8, 0x20, 0x53, 0xa8, 0xa1, 0x45, 0x9f, 0x8e, 0x3d, 0x3b, 0x90, 0x8a, 0xf0, - 0xcc, 0x38, 0x20, 0x59, 0xf4, 0xe4, 0x9b, 0x39, 0x58, 0xd0, 0xf4, 0xe4, 0xc2, 0xcc, 0x11, 0x43, - 0x44, 0x4f, 0xe3, 0x93, 0x97, 0x0c, 0xab, 0xdc, 0x0f, 0x8d, 0x0f, 0x49, 0x42, 0x15, 0xef, 0xc7, - 0xe5, 0xaa, 0xb3, 0x44, 0x3f, 0x1e, 0x62, 0xa1, 0xe2, 0x9a, 0x9e, 0xd1, 0x17, 0x6a, 0x62, 0x5d, - 0x4b, 0x34, 0xe3, 0x7a, 0xb2, 0xbf, 0x85, 0xa2, 0x2b, 0x17, 0x29, 0xba, 0xd0, 0x02, 0x98, 0x0d, - 0x84, 0x88, 0x2e, 0x87, 0x3f, 0x8c, 0xcf, 0xa8, 0xfb, 0x90, 0x10, 0x0b, 0x07, 0xee, 0x43, 0xc6, - 0xff, 0x3c, 0x06, 0x33, 0x89, 0x69, 0x21, 0xee, 0xa9, 0xb9, 0xd4, 0x3d, 0xb5, 0x01, 0xc0, 0x55, - 0xbd, 0x43, 0xea, 0x64, 0xa5, 0x83, 0xf2, 0xa4, 0x08, 0x2f, 0x10, 0xad, 0x29, 0x85, 0x0d, 0x63, - 0xca, 0x57, 0xec, 0x90, 0x3a, 0xf2, 0x88, 0x29, 0x5f, 0xf4, 0x0a, 0xd3, 0x98, 0x0d, 0x59, 0x82, - 0x51, 0x0c, 0x46, 0xad, 0xfa, 0x87, 0x3b, 0x0c, 0x60, 0x72, 0x38, 0x79, 0x01, 0xc6, 0x98, 0x10, - 0x55, 0xab, 0x8a, 0x4d, 0x10, 0xcf, 0x16, 0x26, 0x65, 0x31, 0x89, 0x45, 0x14, 0x91, 0xeb, 0x50, - 0xe2, 0x7f, 0x89, 0xf0, 0x53, 0x63, 0xba, 0xc1, 0xae, 0xe5, 0xb4, 0x64, 0x04, 0x2a, 0x0d, 0x8f, - 0xdd, 0x2e, 0x1a, 0x3d, 0x54, 0xeb, 0xd4, 0xaa, 0x22, 0xb5, 0x04, 0xde, 0x2e, 0x02, 0x0e, 0x64, - 0x55, 0xc4, 0x08, 0x4c, 0x96, 0x11, 0x5e, 0x5a, 0x45, 0xbc, 0x53, 0xa2, 0x2c, 0xc3, 0xbd, 0xb3, - 0x4c, 0x51, 0x42, 0x2e, 0xf1, 0x97, 0x18, 0x14, 0x0b, 0x79, 0x7e, 0x65, 0x7c, 0xb7, 0x40, 0xc5, - 0x04, 0xca, 0x86, 0x51, 0x31, 0xab, 0x9c, 0xfd, 0xbd, 0xd6, 0xb1, 0x9d, 0xb6, 0xd8, 0x56, 0xb0, - 0x72, 0xc4, 0xa5, 0x0c, 0x6a, 0xc6, 0x08, 0xe4, 0x6d, 0x98, 0xe6, 0x79, 0x50, 0x3b, 0x1d, 0xcf, - 0x45, 0xf6, 0x93, 0x71, 0x80, 0x49, 0x91, 0x9b, 0x95, 0x15, 0xf1, 0x5a, 0x12, 0xb8, 0xec, 0x3c, - 0xc1, 0x57, 0xde, 0x1e, 0x7f, 0x23, 0x2a, 0xc5, 0xe7, 0x09, 0x92, 0x06, 0x1c, 0x6e, 0xaa, 0x48, - 0xe4, 0x0d, 0x98, 0x62, 0x3f, 0x6f, 0x3a, 0x0f, 0x29, 0xaf, 0x70, 0x2a, 0x36, 0x95, 0x40, 0xaa, - 0x5d, 0x56, 0xc2, 0xeb, 0xd3, 0x31, 0xc9, 0xfb, 0x70, 0x0a, 0x39, 0x35, 0xbd, 0x2e, 0x6d, 0x55, - 0x76, 0x76, 0x9c, 0xb6, 0xc3, 0x8d, 0x21, 0xa7, 0x63, 0x1b, 0x26, 0x5e, 0x31, 0x62, 0x58, 0x76, - 0x8c, 0x62, 0x66, 0x53, 0x92, 0x07, 0x50, 0x5e, 0xed, 0x05, 0xa1, 0xd7, 0xa9, 0x84, 0xa1, 0xef, - 0x6c, 0xf7, 0x42, 0x1a, 0x2c, 0xcc, 0x68, 0xe1, 0x88, 0xd8, 0xe2, 0x88, 0x0a, 0xb9, 0x3e, 0xa8, - 0x89, 0x14, 0x96, 0x1d, 0x91, 0x98, 0x29, 0x26, 0xc6, 0xff, 0x94, 0x83, 0x29, 0x8d, 0x94, 0xbc, - 0x0e, 0xa5, 0x1b, 0xbe, 0x43, 0xdd, 0x56, 0xfb, 0x40, 0xb9, 0xa8, 0xe2, 0x2d, 0x66, 0x47, 0xc0, - 0x79, 0xab, 0x35, 0xb4, 0x48, 0xcf, 0x93, 0xcf, 0xb4, 0x54, 0xbe, 0xc2, 0xc3, 0x14, 0x88, 0x09, - 0x5a, 0x88, 0xe3, 0xa3, 0xe1, 0x04, 0x15, 0xb3, 0x53, 0x41, 0x21, 0xef, 0xc0, 0x18, 0x7f, 0x0f, + // 34333 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6d, 0x8c, 0x5c, 0x59, + 0x76, 0x18, 0xb6, 0x55, 0xd5, 0x1f, 0xd5, 0xa7, 0xbf, 0xaa, 0x6f, 0x37, 0xc9, 0x66, 0x73, 0x38, + 0xc5, 0x79, 0x33, 0xc3, 0x21, 0x67, 0x87, 0xe4, 0xb2, 0xb9, 0xc3, 0xdd, 0xf9, 0xde, 0xea, 0x0f, + 0xb2, 0x8b, 0xec, 0x26, 0x6b, 0x5e, 0x75, 0x93, 0xb3, 0xda, 0x8f, 0xb7, 0xaf, 0xab, 0x6e, 0x77, + 0xbf, 0xe9, 0xaa, 0xf7, 0x6a, 0xdf, 0x7b, 0x45, 0xb2, 0xb5, 0x56, 0x6c, 0xc7, 0xda, 0xc8, 0x82, + 0xb2, 0xfa, 0xb2, 0x64, 0xad, 0x03, 0x5b, 0x10, 0x64, 0x29, 0x70, 0x6c, 0xc8, 0x89, 0x25, 0x3b, + 0x71, 0x20, 0x58, 0x5e, 0x05, 0x96, 0xac, 0x18, 0x81, 0x25, 0xd8, 0x09, 0xe2, 0x2c, 0x84, 0x16, + 0x6c, 0x19, 0x41, 0xd2, 0x40, 0x02, 0x39, 0x01, 0x02, 0x64, 0x05, 0x23, 0xc1, 0x3d, 0xf7, 0xde, + 0xf7, 0xee, 0x7d, 0xef, 0x55, 0x75, 0xf5, 0x0c, 0x47, 0x16, 0x17, 0xfa, 0x43, 0x76, 0x9d, 0x7b, + 0xce, 0xb9, 0xef, 0x7e, 0x9f, 0x7b, 0xee, 0xf9, 0x80, 0x17, 0x42, 0xda, 0xa2, 0x1d, 0xcf, 0x0f, + 0xaf, 0xb5, 0xe8, 0xae, 0xdd, 0x38, 0xb8, 0x16, 0x1e, 0x74, 0x68, 0xc0, 0xff, 0xbd, 0xda, 0xf1, + 0xbd, 0xd0, 0x23, 0xc3, 0xf8, 0x63, 0x61, 0x6e, 0xd7, 0xdb, 0xf5, 0x10, 0x72, 0x8d, 0xfd, 0xc5, + 0x0b, 0x17, 0x9e, 0xdf, 0xf5, 0xbc, 0xdd, 0x16, 0xbd, 0x86, 0xbf, 0xb6, 0xbb, 0x3b, 0xd7, 0x9a, + 0x5d, 0xdf, 0x0e, 0x1d, 0xcf, 0x15, 0xe5, 0xe5, 0x64, 0x79, 0xe8, 0xb4, 0x69, 0x10, 0xda, 0xed, + 0x4e, 0x2f, 0x06, 0x8f, 0x7d, 0xbb, 0xd3, 0xa1, 0xbe, 0xa8, 0x7d, 0xe1, 0x72, 0xf4, 0x81, 0x76, + 0x18, 0x32, 0x4a, 0xc6, 0xfc, 0xda, 0xa3, 0xeb, 0xea, 0x4f, 0x81, 0x7a, 0xb3, 0x47, 0x5b, 0xfc, + 0x6e, 0x10, 0xd2, 0xa6, 0xd5, 0xa4, 0x8f, 0x9c, 0x06, 0xb5, 0x7c, 0xfa, 0xf5, 0xae, 0xe3, 0xd3, + 0x36, 0x75, 0x43, 0x41, 0x77, 0x25, 0x9b, 0x4e, 0x7e, 0x48, 0xe2, 0x8b, 0x8c, 0x9f, 0x2f, 0xc0, + 0xd8, 0x5d, 0x4a, 0x3b, 0x95, 0x96, 0xf3, 0x88, 0x92, 0x17, 0x61, 0xe8, 0x9e, 0xdd, 0xa6, 0xf3, + 0xb9, 0x0b, 0xb9, 0x4b, 0x63, 0x4b, 0xd3, 0x47, 0x87, 0xe5, 0xf1, 0x80, 0xfa, 0x8f, 0xa8, 0x6f, + 0xb9, 0x76, 0x9b, 0x9a, 0x58, 0x48, 0x3e, 0x0d, 0x63, 0xec, 0xff, 0xa0, 0x63, 0x37, 0xe8, 0x7c, + 0x1e, 0x31, 0x27, 0x8f, 0x0e, 0xcb, 0x63, 0xae, 0x04, 0x9a, 0x71, 0x39, 0xa9, 0xc2, 0xe8, 0xea, + 0x93, 0x8e, 0xe3, 0xd3, 0x60, 0x7e, 0xe8, 0x42, 0xee, 0xd2, 0xf8, 0xe2, 0xc2, 0x55, 0xde, 0x47, + 0x57, 0x65, 0x1f, 0x5d, 0xdd, 0x94, 0x9d, 0xb8, 0x34, 0xfb, 0x3b, 0x87, 0xe5, 0x4f, 0x1d, 0x1d, + 0x96, 0x47, 0x29, 0x27, 0xf9, 0xc9, 0x3f, 0x28, 0xe7, 0x4c, 0x49, 0x4f, 0xde, 0x86, 0xa1, 0xcd, + 0x83, 0x0e, 0x9d, 0x1f, 0xbb, 0x90, 0xbb, 0x34, 0xb5, 0xf8, 0xfc, 0x55, 0x3e, 0xac, 0xd1, 0xc7, + 0xc7, 0x7f, 0x31, 0xac, 0xa5, 0xe2, 0xd1, 0x61, 0x79, 0x88, 0xa1, 0x98, 0x48, 0x45, 0xae, 0xc0, + 0xc8, 0x9a, 0x17, 0x84, 0xd5, 0x95, 0x79, 0xc0, 0x4f, 0x3e, 0x75, 0x74, 0x58, 0x9e, 0xd9, 0xf3, + 0x82, 0xd0, 0x72, 0x9a, 0xaf, 0x79, 0x6d, 0x27, 0xa4, 0xed, 0x4e, 0x78, 0x60, 0x0a, 0x24, 0xe3, + 0x09, 0x4c, 0x6a, 0xfc, 0xc8, 0x38, 0x8c, 0x6e, 0xdd, 0xbb, 0x7b, 0xef, 0xfe, 0xc3, 0x7b, 0xa5, + 0x4f, 0x91, 0x22, 0x0c, 0xdd, 0xbb, 0xbf, 0xb2, 0x5a, 0xca, 0x91, 0x51, 0x28, 0x54, 0x6a, 0xb5, + 0x52, 0x9e, 0x4c, 0x40, 0x71, 0xa5, 0xb2, 0x59, 0x59, 0xaa, 0xd4, 0x57, 0x4b, 0x05, 0x32, 0x0b, + 0xd3, 0x0f, 0xab, 0xf7, 0x56, 0xee, 0x3f, 0xac, 0x5b, 0x2b, 0xab, 0xf5, 0xbb, 0x9b, 0xf7, 0x6b, + 0xa5, 0x21, 0x32, 0x05, 0x70, 0x77, 0x6b, 0x69, 0xd5, 0xbc, 0xb7, 0xba, 0xb9, 0x5a, 0x2f, 0x0d, + 0x93, 0x39, 0x28, 0x49, 0x12, 0xab, 0xbe, 0x6a, 0x3e, 0xa8, 0x2e, 0xaf, 0x96, 0x46, 0xee, 0x0c, + 0x15, 0x0b, 0xa5, 0x21, 0x73, 0x74, 0x9d, 0xda, 0x01, 0xad, 0xae, 0x18, 0x7f, 0xb3, 0x00, 0xc5, + 0x0d, 0x1a, 0xda, 0x4d, 0x3b, 0xb4, 0xc9, 0x73, 0xda, 0xf8, 0x60, 0x13, 0x95, 0x81, 0x79, 0x31, + 0x3d, 0x30, 0xc3, 0x47, 0x87, 0xe5, 0xdc, 0x15, 0x75, 0x40, 0xde, 0x82, 0xf1, 0x15, 0x1a, 0x34, + 0x7c, 0xa7, 0xc3, 0x26, 0xdb, 0x7c, 0x01, 0xd1, 0xce, 0x1e, 0x1d, 0x96, 0x4f, 0x35, 0x63, 0xb0, + 0xd2, 0x21, 0x2a, 0x36, 0xa9, 0xc2, 0xc8, 0xba, 0xbd, 0x4d, 0x5b, 0xc1, 0xfc, 0xf0, 0x85, 0xc2, + 0xa5, 0xf1, 0xc5, 0x73, 0x62, 0x10, 0xe4, 0x07, 0x5e, 0xe5, 0xa5, 0xab, 0x6e, 0xe8, 0x1f, 0x2c, + 0xcd, 0x1d, 0x1d, 0x96, 0x4b, 0x2d, 0x04, 0xa8, 0x1d, 0xcc, 0x51, 0x48, 0x3d, 0x9e, 0x18, 0x23, + 0xc7, 0x4e, 0x8c, 0xf3, 0xbf, 0x73, 0x58, 0xce, 0xb1, 0x01, 0x13, 0x13, 0x23, 0xe6, 0xa7, 0x4f, + 0x91, 0x45, 0x28, 0x9a, 0xf4, 0x91, 0x13, 0xb0, 0x96, 0x15, 0xb1, 0x65, 0xa7, 0x8f, 0x0e, 0xcb, + 0xc4, 0x17, 0x30, 0xe5, 0x33, 0x22, 0xbc, 0x85, 0x37, 0x60, 0x5c, 0xf9, 0x6a, 0x52, 0x82, 0xc2, + 0x3e, 0x3d, 0xe0, 0x3d, 0x6c, 0xb2, 0x3f, 0xc9, 0x1c, 0x0c, 0x3f, 0xb2, 0x5b, 0x5d, 0xd1, 0xa5, + 0x26, 0xff, 0xf1, 0x66, 0xfe, 0xf3, 0xb9, 0x3b, 0x43, 0xc5, 0xd1, 0x52, 0xd1, 0xcc, 0x57, 0x57, + 0x8c, 0x9f, 0x1e, 0x82, 0xa2, 0xe9, 0xf1, 0x05, 0x4c, 0x2e, 0xc3, 0x70, 0x3d, 0xb4, 0x43, 0x39, + 0x4c, 0xb3, 0x47, 0x87, 0xe5, 0x69, 0xb6, 0xb8, 0xa9, 0x52, 0x3f, 0xc7, 0x60, 0xa8, 0xb5, 0x3d, + 0x3b, 0x90, 0xc3, 0x85, 0xa8, 0x1d, 0x06, 0x50, 0x51, 0x11, 0x83, 0x5c, 0x84, 0xa1, 0x0d, 0xaf, + 0x49, 0xc5, 0x88, 0x91, 0xa3, 0xc3, 0xf2, 0x54, 0xdb, 0x6b, 0xaa, 0x88, 0x58, 0x4e, 0x5e, 0x83, + 0xb1, 0xe5, 0xae, 0xef, 0x53, 0x97, 0xcd, 0xf5, 0x21, 0x44, 0x9e, 0x3a, 0x3a, 0x2c, 0x43, 0x83, + 0x03, 0x2d, 0xa7, 0x69, 0xc6, 0x08, 0x6c, 0x18, 0xea, 0xa1, 0xed, 0x87, 0xb4, 0x39, 0x3f, 0x3c, + 0xd0, 0x30, 0xb0, 0xf5, 0x39, 0x13, 0x70, 0x92, 0xe4, 0x30, 0x08, 0x4e, 0x64, 0x0d, 0xc6, 0x6f, + 0xfb, 0x76, 0x83, 0xd6, 0xa8, 0xef, 0x78, 0x4d, 0x1c, 0xdf, 0xc2, 0xd2, 0xc5, 0xa3, 0xc3, 0xf2, + 0xe9, 0x5d, 0x06, 0xb6, 0x3a, 0x08, 0x8f, 0xa9, 0xbf, 0x77, 0x58, 0x2e, 0xae, 0x88, 0xad, 0xd6, + 0x54, 0x49, 0xc9, 0xd7, 0xd8, 0xe0, 0x04, 0x21, 0x76, 0x2d, 0x6d, 0xce, 0x8f, 0x1e, 0xfb, 0x89, + 0x86, 0xf8, 0xc4, 0xd3, 0x2d, 0x3b, 0x08, 0x2d, 0x9f, 0xd3, 0x25, 0xbe, 0x53, 0x65, 0x49, 0xee, + 0x43, 0xb1, 0xde, 0xd8, 0xa3, 0xcd, 0x6e, 0x8b, 0xe2, 0x94, 0x19, 0x5f, 0x3c, 0x23, 0x26, 0xb5, + 0x1c, 0x4f, 0x59, 0xbc, 0xb4, 0x20, 0x78, 0x93, 0x40, 0x40, 0xd4, 0xf9, 0x24, 0xb1, 0xde, 0x2c, + 0x7e, 0xfb, 0x17, 0xca, 0x9f, 0xfa, 0x0b, 0xbf, 0x7f, 0xe1, 0x53, 0xc6, 0x7f, 0x93, 0x87, 0x52, + 0x92, 0x09, 0xd9, 0x81, 0xc9, 0xad, 0x4e, 0xd3, 0x0e, 0xe9, 0x72, 0xcb, 0xa1, 0x6e, 0x18, 0xe0, + 0x24, 0xe9, 0xdf, 0xa6, 0x97, 0x44, 0xbd, 0xf3, 0x5d, 0x24, 0xb4, 0x1a, 0x9c, 0x32, 0xd1, 0x2a, + 0x9d, 0x6d, 0x5c, 0x4f, 0x1d, 0x37, 0xf0, 0x00, 0x67, 0xd8, 0xc9, 0xea, 0xe1, 0x5b, 0x7f, 0x8f, + 0x7a, 0x04, 0x5b, 0x31, 0x81, 0xdc, 0xe6, 0xf6, 0x01, 0xce, 0xcc, 0xc1, 0x27, 0x10, 0x23, 0xc9, + 0x98, 0x40, 0x0c, 0x6c, 0xfc, 0xdb, 0x1c, 0x4c, 0x99, 0x34, 0xf0, 0xba, 0x7e, 0x83, 0xae, 0x51, + 0xbb, 0x49, 0x7d, 0x36, 0xfd, 0xef, 0x3a, 0x6e, 0x53, 0xac, 0x29, 0x9c, 0xfe, 0xfb, 0x8e, 0xab, + 0x6e, 0xdd, 0x58, 0x4e, 0x3e, 0x03, 0xa3, 0xf5, 0xee, 0x36, 0xa2, 0xe6, 0xe3, 0x1d, 0x20, 0xe8, + 0x6e, 0x5b, 0x09, 0x74, 0x89, 0x46, 0xae, 0xc1, 0xe8, 0x03, 0xea, 0x07, 0xf1, 0x6e, 0x88, 0x47, + 0xc3, 0x23, 0x0e, 0x52, 0x09, 0x04, 0x16, 0xb9, 0x1d, 0xef, 0xc8, 0xe2, 0x50, 0x9b, 0x4e, 0xec, + 0x83, 0xf1, 0x54, 0x69, 0x0b, 0x88, 0x3a, 0x55, 0x24, 0x96, 0xf1, 0xaf, 0xf2, 0x50, 0x5a, 0xb1, + 0x43, 0x7b, 0xdb, 0x0e, 0x44, 0x7f, 0x3e, 0xb8, 0xc1, 0xf6, 0x78, 0xa5, 0xa1, 0xb8, 0xc7, 0xb3, + 0x2f, 0xff, 0xc8, 0xcd, 0x7b, 0x39, 0xd9, 0xbc, 0x71, 0x76, 0xc2, 0x8a, 0xe6, 0xc5, 0x8d, 0x7a, + 0xe7, 0xf8, 0x46, 0x95, 0x44, 0xa3, 0x8a, 0xb2, 0x51, 0x71, 0x53, 0xc8, 0x3b, 0x30, 0x54, 0xef, + 0xd0, 0x86, 0xd8, 0x44, 0xe4, 0xb9, 0xa0, 0x37, 0x8e, 0x21, 0x3c, 0xb8, 0xb1, 0x34, 0x21, 0xd8, + 0x0c, 0x05, 0x1d, 0xda, 0x30, 0x91, 0x8c, 0xac, 0xc2, 0x08, 0xdb, 0x10, 0xbb, 0xf2, 0x30, 0x38, + 0x9f, 0xcd, 0x00, 0x51, 0x1e, 0xdc, 0x58, 0x9a, 0x12, 0x2c, 0x46, 0x02, 0x84, 0x98, 0x82, 0x58, + 0x59, 0x7b, 0xff, 0xb0, 0x00, 0x73, 0x59, 0xb5, 0xab, 0xdd, 0x31, 0xd2, 0xa7, 0x3b, 0x2e, 0x41, + 0x91, 0x49, 0x02, 0xec, 0x74, 0xc5, 0x5d, 0x67, 0x6c, 0x69, 0x82, 0xb5, 0x7c, 0x4f, 0xc0, 0xcc, + 0xa8, 0x94, 0xbc, 0x18, 0x09, 0x16, 0xc5, 0x98, 0x9f, 0x10, 0x2c, 0xa4, 0x38, 0xc1, 0xa6, 0x8c, + 0xdc, 0x09, 0x50, 0xfe, 0x88, 0x7b, 0x57, 0x82, 0xe3, 0x29, 0xe3, 0x0b, 0x88, 0x76, 0x5a, 0xc9, + 0xb3, 0x65, 0x15, 0x8a, 0xb2, 0x59, 0xf3, 0x13, 0xc8, 0x68, 0x26, 0xd1, 0x55, 0x0f, 0x6e, 0xf0, + 0x39, 0xd1, 0x14, 0xbf, 0x55, 0x36, 0x12, 0x87, 0xdc, 0x80, 0x62, 0xcd, 0xf7, 0x9e, 0x1c, 0x54, + 0x57, 0x82, 0xf9, 0xc9, 0x0b, 0x85, 0x4b, 0x63, 0x4b, 0x67, 0x8e, 0x0e, 0xcb, 0xb3, 0x1d, 0x06, + 0xb3, 0x9c, 0xa6, 0x7a, 0x60, 0x47, 0x88, 0x77, 0x86, 0x8a, 0xb9, 0x52, 0xfe, 0xce, 0x50, 0x31, + 0x5f, 0x2a, 0x70, 0x29, 0xe5, 0xce, 0x50, 0x71, 0xa8, 0x34, 0x7c, 0x67, 0xa8, 0x38, 0x8c, 0x72, + 0xcb, 0x58, 0x09, 0xee, 0x0c, 0x15, 0xc7, 0x4b, 0x13, 0x9a, 0xd0, 0x80, 0x0c, 0x42, 0xaf, 0xe1, + 0xb5, 0xcc, 0xc2, 0x96, 0x59, 0x35, 0x47, 0x96, 0x2b, 0xcb, 0xd4, 0x0f, 0xcd, 0x42, 0xe5, 0x61, + 0xdd, 0x9c, 0x5c, 0x39, 0x70, 0xed, 0xb6, 0xd3, 0xe0, 0x27, 0xb0, 0x59, 0xb8, 0xbd, 0x5c, 0x33, + 0x5c, 0x38, 0x9d, 0x3d, 0xec, 0x64, 0x13, 0x26, 0x36, 0x6d, 0x7f, 0x97, 0x86, 0x6b, 0xd4, 0x6e, + 0x85, 0x7b, 0xf3, 0x53, 0xd8, 0x01, 0xb3, 0xa2, 0x03, 0xd4, 0xa2, 0xa5, 0x73, 0x47, 0x87, 0xe5, + 0x33, 0x21, 0x42, 0xac, 0x3d, 0x04, 0x29, 0x4d, 0xd2, 0xb8, 0x18, 0x15, 0x98, 0x8a, 0xfb, 0x6e, + 0xdd, 0x09, 0x42, 0x72, 0x0d, 0xc6, 0x24, 0x84, 0xed, 0xcf, 0x85, 0xcc, 0x5e, 0x36, 0x63, 0x1c, + 0xe3, 0xb7, 0xf3, 0x00, 0x71, 0xc9, 0x33, 0xba, 0x84, 0x3f, 0xa7, 0x2d, 0xe1, 0x53, 0xc9, 0x15, + 0xd8, 0x7b, 0xf1, 0xbe, 0x97, 0x58, 0xbc, 0x67, 0x92, 0xa4, 0x83, 0x2f, 0xdb, 0x9f, 0x1f, 0x8d, + 0x07, 0x43, 0x2c, 0xd8, 0x4b, 0x10, 0x4d, 0x20, 0xd1, 0xa1, 0xb8, 0x12, 0x3b, 0x72, 0x52, 0x45, + 0xa5, 0xe4, 0x2c, 0xb0, 0x09, 0x26, 0x3a, 0x75, 0xf4, 0xe8, 0xb0, 0x5c, 0xe8, 0xfa, 0x0e, 0x4e, + 0x3a, 0x72, 0x0d, 0xc4, 0xb4, 0x13, 0x1d, 0xc8, 0x66, 0xfb, 0x4c, 0xc3, 0xb6, 0x1a, 0xd4, 0x0f, + 0xe3, 0x1e, 0x9f, 0xcf, 0xc9, 0xd9, 0x49, 0x3a, 0xa0, 0x4f, 0xcd, 0xf9, 0x21, 0x9c, 0x06, 0x97, + 0x32, 0x7b, 0xe5, 0xaa, 0x86, 0xca, 0xa5, 0xdf, 0x0b, 0xf2, 0x30, 0x6d, 0xf2, 0x32, 0x2b, 0x25, + 0x09, 0xeb, 0x15, 0x90, 0x1b, 0xc0, 0x56, 0x84, 0xe8, 0x7d, 0x10, 0xf5, 0x54, 0x1e, 0xd6, 0x97, + 0x4e, 0x09, 0x4e, 0x93, 0xf6, 0x63, 0x95, 0x9c, 0x61, 0x93, 0xb7, 0x80, 0x2d, 0x19, 0xd1, 0xef, + 0x44, 0x10, 0xdd, 0x5e, 0xae, 0x2d, 0xb7, 0xbc, 0x6e, 0xb3, 0xfe, 0xfe, 0x7a, 0x4c, 0xbc, 0xdb, + 0xe8, 0xa8, 0xc4, 0xb7, 0x97, 0x6b, 0xe4, 0x2d, 0x18, 0xae, 0xfc, 0x60, 0xd7, 0xa7, 0x42, 0xac, + 0x9a, 0x90, 0x75, 0x32, 0xd8, 0xd2, 0x19, 0x41, 0x38, 0x6d, 0xb3, 0x9f, 0xaa, 0x38, 0x8a, 0xe5, + 0xac, 0xe6, 0xcd, 0xf5, 0xba, 0x10, 0x99, 0x48, 0xa2, 0x5b, 0x36, 0xd7, 0x95, 0xcf, 0x0e, 0xb5, + 0x56, 0x33, 0x2a, 0x72, 0x0d, 0xf2, 0x95, 0x15, 0xbc, 0xc8, 0x8d, 0x2f, 0x8e, 0xc9, 0x6a, 0x57, + 0x96, 0xe6, 0x04, 0xc9, 0x84, 0xad, 0x2e, 0x83, 0x7c, 0x65, 0x85, 0x2c, 0xc1, 0xf0, 0xc6, 0x41, + 0xfd, 0xfd, 0x75, 0xb1, 0x79, 0xca, 0x25, 0x8f, 0xb0, 0xfb, 0xb8, 0xcd, 0x04, 0xf1, 0x17, 0xb7, + 0x0f, 0x82, 0xaf, 0xb7, 0xd4, 0x2f, 0x46, 0x34, 0x52, 0x83, 0xb1, 0x4a, 0xb3, 0xed, 0xb8, 0x5b, + 0x01, 0xf5, 0xe7, 0xc7, 0x91, 0xcf, 0x7c, 0xe2, 0xbb, 0xa3, 0xf2, 0xa5, 0xf9, 0xa3, 0xc3, 0xf2, + 0x9c, 0xcd, 0x7e, 0x5a, 0xdd, 0x80, 0xfa, 0x0a, 0xb7, 0x98, 0x09, 0xa9, 0x01, 0x6c, 0x78, 0xee, + 0xae, 0x57, 0x09, 0x5b, 0x76, 0x90, 0xd8, 0x8e, 0xe3, 0x82, 0x48, 0xea, 0x39, 0xd5, 0x66, 0x30, + 0xcb, 0x66, 0x40, 0x85, 0xa1, 0xc2, 0x83, 0xdc, 0x82, 0x91, 0xfb, 0xbe, 0xdd, 0x68, 0xd1, 0xf9, + 0x49, 0xe4, 0x36, 0x27, 0xb8, 0x71, 0xa0, 0x6c, 0xe9, 0xbc, 0x60, 0x58, 0xf2, 0x10, 0xac, 0xde, + 0xae, 0x38, 0xe2, 0xc2, 0x43, 0x20, 0xe9, 0x39, 0x99, 0x71, 0xb7, 0xf9, 0xb4, 0x7a, 0xb7, 0x89, + 0x17, 0xfd, 0xb2, 0xd7, 0x6e, 0xdb, 0x6e, 0x13, 0x69, 0x1f, 0x2c, 0x2a, 0x57, 0x1e, 0xe3, 0xeb, + 0x30, 0x93, 0xea, 0xac, 0x63, 0xae, 0xa5, 0xef, 0xc2, 0xf4, 0x0a, 0xdd, 0xb1, 0xbb, 0xad, 0x30, + 0x3a, 0xb9, 0xf8, 0x12, 0xc5, 0x0b, 0x62, 0x93, 0x17, 0x59, 0xf2, 0xb8, 0x32, 0x93, 0xc8, 0xc6, + 0x3b, 0x30, 0xa9, 0x35, 0x9f, 0xdd, 0x70, 0x2a, 0xdd, 0xa6, 0x13, 0xe2, 0x40, 0xe6, 0xe2, 0x1b, + 0x8e, 0xcd, 0x80, 0x38, 0x5c, 0x66, 0x8c, 0x60, 0xfc, 0x92, 0x2a, 0x64, 0xc9, 0x93, 0xe4, 0x4a, + 0xb4, 0x1f, 0xe4, 0x62, 0x91, 0x2f, 0xb5, 0x1f, 0x44, 0xbb, 0xc1, 0x65, 0xbe, 0x36, 0xf3, 0xa9, + 0xb5, 0x39, 0x2e, 0x46, 0xa2, 0x60, 0x3f, 0x0e, 0xf8, 0x8a, 0x8c, 0x66, 0x6a, 0xe1, 0xa3, 0xcf, + 0xd4, 0xf7, 0x60, 0x62, 0xc3, 0x76, 0xed, 0x5d, 0xda, 0x64, 0x2d, 0xe0, 0x7b, 0xcf, 0x18, 0x3f, + 0xd2, 0xda, 0x1c, 0x8e, 0xad, 0x54, 0x27, 0x91, 0x46, 0x40, 0xae, 0xcb, 0x95, 0x3d, 0x9c, 0xb1, + 0xb2, 0x27, 0x45, 0xed, 0xc3, 0xb8, 0xb2, 0xc5, 0x7a, 0x36, 0xbe, 0x33, 0x86, 0x6d, 0x24, 0xaf, + 0xc1, 0x88, 0x49, 0x77, 0xd9, 0x51, 0x93, 0x8b, 0x07, 0xc9, 0x47, 0x88, 0xda, 0x31, 0x1c, 0x07, + 0xe5, 0x1a, 0xda, 0x0c, 0xf6, 0x9c, 0x9d, 0x50, 0xf4, 0x4e, 0x24, 0xd7, 0x08, 0xb0, 0x22, 0xd7, + 0x08, 0x88, 0x7e, 0x0b, 0xe7, 0x30, 0xb6, 0xfb, 0x99, 0x2b, 0x75, 0xd1, 0x69, 0xb2, 0x87, 0xcd, + 0x15, 0x65, 0x1b, 0xf1, 0x35, 0xa9, 0x84, 0x61, 0x93, 0x9b, 0x30, 0x56, 0x69, 0x34, 0xbc, 0xae, + 0x72, 0xd5, 0xe5, 0xeb, 0x96, 0x03, 0x75, 0xcd, 0x4e, 0x8c, 0x4a, 0xea, 0x30, 0xbe, 0xca, 0xee, + 0x87, 0xce, 0xb2, 0xdd, 0xd8, 0x93, 0x9d, 0x24, 0xf7, 0x30, 0xa5, 0x24, 0x5e, 0xb9, 0x14, 0x81, + 0x0d, 0x06, 0x54, 0x75, 0x23, 0x0a, 0x2e, 0xd9, 0x84, 0xf1, 0x3a, 0x6d, 0xf8, 0x34, 0xac, 0x87, + 0x9e, 0x4f, 0x13, 0x5b, 0xb2, 0x52, 0xb2, 0xf4, 0xbc, 0xbc, 0xa2, 0x06, 0x08, 0xb4, 0x02, 0x06, + 0x55, 0xb9, 0x2a, 0xc8, 0xfc, 0xae, 0xd1, 0xf6, 0xfc, 0x83, 0x95, 0x25, 0xb1, 0x4d, 0xc7, 0x67, + 0x3a, 0x07, 0xab, 0x77, 0x0d, 0x06, 0x69, 0x6e, 0xeb, 0x77, 0x0d, 0x8e, 0x85, 0x23, 0xb5, 0x52, + 0x47, 0x59, 0x4e, 0x6c, 0xda, 0xd3, 0x71, 0x2f, 0x23, 0x58, 0x19, 0xa9, 0x66, 0x80, 0x92, 0xa0, + 0x36, 0x52, 0x02, 0x8b, 0x74, 0x80, 0xc8, 0x51, 0xe3, 0xe2, 0x59, 0x8b, 0x06, 0x81, 0xd8, 0xcb, + 0xcf, 0x26, 0x06, 0x3f, 0x46, 0x58, 0x7a, 0x59, 0x30, 0x3f, 0x2f, 0xa7, 0x81, 0xb8, 0x5e, 0xb2, + 0x42, 0xa5, 0x9e, 0x0c, 0xde, 0xe4, 0x0d, 0x80, 0xd5, 0x27, 0x21, 0xf5, 0x5d, 0xbb, 0x15, 0xa9, + 0xef, 0x50, 0x63, 0x45, 0x05, 0x54, 0x1f, 0x68, 0x05, 0x99, 0x2c, 0xc3, 0x64, 0x25, 0x08, 0xba, + 0x6d, 0x6a, 0x7a, 0x2d, 0x5a, 0x31, 0xef, 0xe1, 0xbe, 0x3f, 0xb6, 0x74, 0xfe, 0xe8, 0xb0, 0x7c, + 0xd6, 0xc6, 0x02, 0xcb, 0xf7, 0x5a, 0xd4, 0xb2, 0x7d, 0x75, 0x76, 0xeb, 0x34, 0xe4, 0x3e, 0xc0, + 0xfd, 0x0e, 0x75, 0xeb, 0xd4, 0xf6, 0x1b, 0x7b, 0x89, 0x6d, 0x3e, 0x2e, 0x58, 0x7a, 0x4e, 0xb4, + 0x70, 0xce, 0xeb, 0x50, 0x37, 0x40, 0x98, 0xfa, 0x55, 0x31, 0x26, 0x79, 0x08, 0xd3, 0xd5, 0xca, + 0x46, 0xcd, 0x6b, 0x39, 0x8d, 0x03, 0x21, 0x39, 0x4d, 0xa1, 0x52, 0xf3, 0xb4, 0xe0, 0x9a, 0x28, + 0xe5, 0xdb, 0x93, 0x63, 0xb7, 0xad, 0x0e, 0x42, 0x2d, 0x21, 0x3f, 0x25, 0xb9, 0x90, 0x2f, 0xb2, + 0x39, 0x18, 0x30, 0x61, 0x70, 0xd3, 0xde, 0x0d, 0xe6, 0xa7, 0x35, 0x25, 0x5d, 0xe5, 0x61, 0xfd, + 0xaa, 0x52, 0xca, 0xc5, 0x94, 0x05, 0x3e, 0x11, 0x11, 0x6a, 0x85, 0xf6, 0x6e, 0xa0, 0x4f, 0xc4, + 0x08, 0x9b, 0xdc, 0x01, 0x58, 0xf1, 0x1a, 0xdd, 0x36, 0x75, 0xc3, 0x95, 0xa5, 0xf9, 0x92, 0x7e, + 0xf5, 0x88, 0x0a, 0xe2, 0xad, 0xad, 0xe9, 0x35, 0xb4, 0x99, 0xa8, 0x50, 0x2f, 0xbc, 0x0b, 0xa5, + 0xe4, 0x87, 0x9c, 0x50, 0xef, 0x36, 0x59, 0x9a, 0x52, 0x5a, 0xbf, 0xfa, 0xc4, 0x09, 0xc2, 0xc0, + 0xf8, 0x86, 0xb6, 0x02, 0xd9, 0xee, 0x70, 0x97, 0x1e, 0xd4, 0x7c, 0xba, 0xe3, 0x3c, 0x11, 0x9b, + 0x19, 0xee, 0x0e, 0xfb, 0xf4, 0xc0, 0xea, 0x20, 0x54, 0xdd, 0x1d, 0x22, 0x54, 0xf2, 0x59, 0x28, + 0xde, 0xdd, 0xa8, 0xdf, 0xa5, 0x07, 0xd5, 0x15, 0x71, 0x50, 0x71, 0xb2, 0x76, 0x60, 0x31, 0x52, + 0x6d, 0xae, 0x45, 0x98, 0xc6, 0x52, 0xbc, 0x13, 0xb2, 0x9a, 0x97, 0x5b, 0xdd, 0x20, 0xa4, 0x7e, + 0x75, 0x45, 0xad, 0xb9, 0xc1, 0x81, 0x89, 0x7d, 0x29, 0x42, 0x35, 0xfe, 0xbf, 0x3c, 0xee, 0x82, + 0x6c, 0xc2, 0x57, 0xdd, 0x20, 0xb4, 0xdd, 0x06, 0x8d, 0x18, 0xe0, 0x84, 0x77, 0x04, 0x34, 0x31, + 0xe1, 0x63, 0x64, 0xbd, 0xea, 0xfc, 0xc0, 0x55, 0xb3, 0x2a, 0xa5, 0xc2, 0xa5, 0xba, 0xa2, 0x6a, + 0x85, 0x7d, 0x01, 0x4d, 0x54, 0x19, 0x23, 0x93, 0x8b, 0x30, 0x5a, 0xad, 0x6c, 0x54, 0xba, 0xe1, + 0x1e, 0xee, 0xc1, 0x45, 0x2e, 0x9f, 0xb3, 0xd9, 0x6a, 0x77, 0xc3, 0x3d, 0x53, 0x16, 0x92, 0x6b, + 0x78, 0xef, 0x71, 0x69, 0xc8, 0xb5, 0xc7, 0xe2, 0xd0, 0x0d, 0x38, 0x28, 0x71, 0xed, 0x61, 0x20, + 0xf2, 0x2a, 0x0c, 0x3f, 0xa8, 0x2d, 0x57, 0x57, 0xc4, 0x45, 0x1d, 0x4f, 0xa2, 0x47, 0x9d, 0x86, + 0xfe, 0x25, 0x1c, 0x85, 0xac, 0xc2, 0x54, 0x9d, 0x36, 0xba, 0xbe, 0x13, 0x1e, 0xdc, 0xf6, 0xbd, + 0x6e, 0x27, 0x98, 0x1f, 0xc5, 0x3a, 0x70, 0xa5, 0x07, 0xa2, 0xc4, 0xda, 0xc5, 0x22, 0x85, 0x3a, + 0x41, 0x64, 0xfc, 0x66, 0x2e, 0xde, 0x26, 0xc9, 0x45, 0x4d, 0xac, 0x41, 0x95, 0x13, 0x13, 0x6b, + 0x54, 0x95, 0x13, 0x0a, 0x38, 0x26, 0x90, 0xe5, 0x6e, 0x10, 0x7a, 0xed, 0x55, 0xb7, 0xd9, 0xf1, + 0x1c, 0x37, 0x44, 0x2a, 0xde, 0xf9, 0xc6, 0xd1, 0x61, 0xf9, 0xf9, 0x06, 0x96, 0x5a, 0x54, 0x14, + 0x5b, 0x09, 0x2e, 0x19, 0xd4, 0x1f, 0x63, 0x3c, 0x8c, 0x7f, 0x96, 0xd7, 0x8e, 0x37, 0xf6, 0x79, + 0x26, 0xed, 0xb4, 0x9c, 0x06, 0x6a, 0x10, 0xb0, 0xa1, 0xd1, 0xac, 0xc2, 0xcf, 0xf3, 0xe3, 0x52, + 0xde, 0x43, 0x3a, 0xef, 0x0c, 0x6a, 0xf2, 0x05, 0x98, 0x60, 0x92, 0x86, 0xf8, 0x19, 0xcc, 0xe7, + 0xb1, 0xb3, 0x9f, 0x43, 0xe5, 0x61, 0x40, 0xfd, 0x88, 0x8d, 0x26, 0xa2, 0xa8, 0x14, 0xa4, 0x09, + 0xf3, 0x9b, 0xbe, 0xed, 0x06, 0x4e, 0xb8, 0xea, 0x36, 0xfc, 0x03, 0x94, 0x8c, 0x56, 0x5d, 0x7b, + 0xbb, 0x45, 0x9b, 0xd8, 0xdc, 0xe2, 0xd2, 0xa5, 0xa3, 0xc3, 0xf2, 0x4b, 0x21, 0xc7, 0xb1, 0x68, + 0x84, 0x64, 0x51, 0x8e, 0xa5, 0x70, 0xee, 0xc9, 0x89, 0x49, 0x52, 0xb2, 0x5b, 0xf1, 0xed, 0x88, + 0x0b, 0x09, 0x28, 0x49, 0x45, 0xa3, 0xc1, 0xf6, 0x30, 0xf5, 0x33, 0x55, 0x02, 0xe3, 0xff, 0xc9, + 0xc5, 0x07, 0x30, 0x79, 0x1b, 0xc6, 0xc5, 0x8a, 0x51, 0xe6, 0x05, 0xee, 0xa0, 0x72, 0x79, 0x25, + 0x46, 0x56, 0x45, 0x67, 0xf7, 0xfe, 0xca, 0xf2, 0xba, 0x32, 0x37, 0xf0, 0xde, 0x6f, 0x37, 0x5a, + 0x49, 0x2a, 0x89, 0xc6, 0x26, 0xc1, 0xe6, 0x7a, 0x5d, 0xef, 0x15, 0x9c, 0x04, 0x61, 0x2b, 0xc8, + 0xe8, 0x06, 0x05, 0xf9, 0xe3, 0x37, 0xfc, 0x7f, 0xce, 0x65, 0x9d, 0xf3, 0x64, 0x09, 0x26, 0x1f, + 0x7a, 0xfe, 0x3e, 0x8e, 0xaf, 0xd2, 0x09, 0x38, 0xf2, 0x8f, 0x65, 0x41, 0xb2, 0x41, 0x3a, 0x89, + 0xfa, 0x6d, 0x4a, 0x6f, 0xe8, 0xdf, 0x96, 0xe0, 0xa0, 0x11, 0xb0, 0x71, 0x88, 0x38, 0x46, 0xab, + 0x03, 0xc7, 0x21, 0xfe, 0x04, 0x6d, 0x0a, 0xab, 0xe8, 0xc6, 0x3f, 0xca, 0xa9, 0xe7, 0x39, 0xeb, + 0xe4, 0x15, 0xaf, 0x6d, 0x3b, 0xae, 0xd2, 0x1c, 0xfe, 0x1e, 0x86, 0xd0, 0xe4, 0x97, 0x28, 0xc8, + 0xe4, 0x06, 0x14, 0xf9, 0xaf, 0x68, 0xaf, 0x45, 0x2d, 0x9a, 0x20, 0xd4, 0x0f, 0x0a, 0x89, 0x98, + 0x1a, 0x99, 0xc2, 0x49, 0x47, 0xe6, 0x3b, 0x39, 0xf5, 0x28, 0xfe, 0xa8, 0x87, 0x4d, 0xe2, 0x90, + 0xc9, 0x9f, 0xe4, 0x90, 0xf9, 0xd8, 0x4d, 0xf8, 0xad, 0x1c, 0x8c, 0x2b, 0x5a, 0x0a, 0xd6, 0x86, + 0x9a, 0xef, 0x7d, 0x48, 0x1b, 0xa1, 0xde, 0x86, 0x0e, 0x07, 0x26, 0xda, 0x10, 0xa1, 0x7e, 0x9c, + 0x36, 0x2c, 0xc3, 0x68, 0xa5, 0xd5, 0xf2, 0x98, 0x5c, 0xcd, 0x2f, 0x1d, 0x53, 0x52, 0x4c, 0xe2, + 0xd0, 0xa5, 0xb3, 0xf2, 0xad, 0xc2, 0x66, 0x00, 0x4d, 0x96, 0x91, 0x94, 0xc6, 0xcf, 0xe5, 0x22, + 0x2e, 0xa9, 0x4e, 0xc9, 0x9d, 0xb0, 0x53, 0xc8, 0x5d, 0x28, 0xc9, 0xdf, 0xf7, 0x1f, 0x51, 0xdf, + 0x77, 0x9a, 0x72, 0x69, 0x94, 0x8f, 0x0e, 0xcb, 0xe7, 0x22, 0x26, 0x9e, 0x28, 0x54, 0x18, 0xa5, + 0x08, 0x8d, 0x7f, 0x97, 0x13, 0x57, 0xc0, 0x81, 0x4f, 0x31, 0xfd, 0xc4, 0xc9, 0x9f, 0x44, 0x02, + 0xf8, 0x02, 0x0c, 0x9b, 0xb4, 0xe9, 0x04, 0xa2, 0x27, 0x67, 0xd4, 0xeb, 0x26, 0x16, 0xc4, 0x62, + 0xa1, 0xcf, 0x7e, 0xaa, 0xc7, 0x37, 0x96, 0x33, 0x39, 0xbd, 0x1a, 0xdc, 0x6a, 0xd1, 0x27, 0x0e, + 0xdf, 0x6b, 0x84, 0x24, 0x81, 0xa7, 0xb7, 0x13, 0x58, 0x3b, 0xac, 0x44, 0x5c, 0x18, 0xd4, 0x7d, + 0x45, 0xa3, 0x31, 0xbe, 0x08, 0x10, 0x57, 0xc9, 0xba, 0x53, 0x4c, 0x76, 0xc7, 0xdd, 0xe5, 0x72, + 0xa2, 0xe8, 0x03, 0xec, 0xce, 0x46, 0x54, 0x26, 0x84, 0x6a, 0xb5, 0x3b, 0x93, 0x84, 0xc6, 0xff, + 0x5a, 0x80, 0x7c, 0x05, 0xe7, 0xdb, 0x5d, 0x7a, 0x10, 0xda, 0xdb, 0xb7, 0x9c, 0x96, 0xb6, 0x57, + 0xec, 0x23, 0xd4, 0xda, 0x71, 0x34, 0x6d, 0x8c, 0x82, 0xcc, 0xf6, 0x8a, 0xbb, 0xfe, 0xf6, 0xeb, + 0x48, 0xa8, 0xec, 0x15, 0xfb, 0xfe, 0xf6, 0xeb, 0x49, 0xb2, 0x08, 0x91, 0x18, 0x30, 0xc2, 0xf7, + 0x0d, 0xb1, 0xc4, 0xe0, 0xe8, 0xb0, 0x3c, 0xc2, 0xb7, 0x17, 0x53, 0x94, 0x90, 0xb3, 0x50, 0xa8, + 0xd7, 0xee, 0x89, 0x0d, 0x1e, 0xb5, 0x9e, 0x41, 0xc7, 0x35, 0x19, 0x8c, 0xd5, 0xb9, 0xbe, 0x52, + 0xa9, 0xa1, 0x9e, 0x63, 0x38, 0xae, 0xb3, 0xd5, 0xb4, 0x3b, 0x49, 0x4d, 0x47, 0x84, 0x48, 0xde, + 0x81, 0xf1, 0xbb, 0x2b, 0xcb, 0x6b, 0x5e, 0xc0, 0x37, 0xe7, 0x91, 0x78, 0x1a, 0xef, 0x37, 0x1b, + 0x16, 0x3e, 0x6c, 0x24, 0x4f, 0x39, 0x05, 0x9f, 0x58, 0x70, 0x9a, 0xb1, 0x62, 0x43, 0xe2, 0x34, + 0xa8, 0xb8, 0x73, 0xdf, 0x8b, 0x9f, 0x51, 0x5e, 0x39, 0x3a, 0x2c, 0xbf, 0x88, 0x5f, 0x10, 0x70, + 0x14, 0x4b, 0xde, 0xd6, 0x13, 0x5c, 0x7b, 0xb0, 0x21, 0x5f, 0x86, 0x53, 0xe9, 0x92, 0x7a, 0xf4, + 0xfc, 0x72, 0xf1, 0xe8, 0xb0, 0x6c, 0x64, 0xf2, 0x0f, 0xb4, 0xf9, 0x9b, 0xcd, 0xc4, 0xf8, 0x66, + 0x1e, 0xc6, 0x15, 0x2d, 0x26, 0xf9, 0xac, 0x78, 0x75, 0xcf, 0x69, 0xf7, 0x33, 0x05, 0x83, 0x95, + 0x72, 0x95, 0x57, 0xdb, 0x6b, 0x52, 0xf1, 0x06, 0x1f, 0xab, 0x97, 0xf2, 0x83, 0xa8, 0x97, 0xde, + 0x00, 0xe0, 0x53, 0x18, 0xfb, 0x49, 0x11, 0xf6, 0x14, 0xe3, 0x1b, 0x75, 0x5a, 0xc5, 0xc8, 0xe4, + 0x01, 0xcc, 0x6e, 0xfa, 0xdd, 0x20, 0xac, 0x1f, 0x04, 0x21, 0x6d, 0x33, 0x6e, 0x35, 0xcf, 0x6b, + 0x89, 0xe5, 0xf3, 0xd2, 0xd1, 0x61, 0xf9, 0x02, 0x5a, 0x0c, 0x59, 0x01, 0x96, 0xe3, 0x07, 0x58, + 0x1d, 0xcf, 0x53, 0x95, 0x4e, 0x59, 0x0c, 0x0c, 0x13, 0x26, 0x54, 0x95, 0x15, 0x3b, 0xf7, 0xc5, + 0x0b, 0xa5, 0x78, 0x88, 0x50, 0xce, 0x7d, 0xf1, 0x95, 0xe9, 0x17, 0x53, 0x9d, 0xc4, 0xf8, 0xac, + 0xaa, 0x2e, 0x1d, 0x74, 0x5f, 0x32, 0xfe, 0xe3, 0x5c, 0xbc, 0xc9, 0x3f, 0xb8, 0x4e, 0xde, 0x82, + 0x11, 0xfe, 0x22, 0x2c, 0x1e, 0xce, 0x4f, 0x45, 0x2a, 0x07, 0xf5, 0xb9, 0x98, 0xbf, 0x53, 0xfc, + 0x1e, 0xb7, 0x1a, 0xf9, 0x94, 0x29, 0x48, 0xa2, 0x27, 0x0e, 0x5d, 0xdb, 0x29, 0xb9, 0xa3, 0x32, + 0xff, 0x7a, 0xd6, 0x13, 0x87, 0xf1, 0x5b, 0xc3, 0x30, 0xa5, 0xa3, 0xa9, 0xcf, 0xc6, 0xb9, 0x81, + 0x9e, 0x8d, 0xbf, 0x00, 0x45, 0x31, 0xdf, 0xa4, 0xbc, 0xfc, 0x12, 0x3e, 0xfc, 0x08, 0x98, 0x66, + 0x0e, 0x01, 0x7c, 0x38, 0x4c, 0xaf, 0x45, 0xcd, 0x88, 0x8a, 0x2c, 0x2a, 0x8f, 0x92, 0x85, 0x58, + 0x84, 0x94, 0x8f, 0x92, 0xea, 0x72, 0x8e, 0x9e, 0x27, 0xaf, 0xc0, 0x08, 0xbb, 0x7d, 0x45, 0x0a, + 0x32, 0xfc, 0x4a, 0x76, 0x31, 0x4b, 0xd8, 0x3d, 0x71, 0x24, 0xf2, 0x10, 0x8a, 0xeb, 0x76, 0x10, + 0xd6, 0x29, 0x75, 0x07, 0x30, 0x08, 0x29, 0x8b, 0xae, 0x9a, 0x45, 0x6b, 0x8b, 0x80, 0x52, 0x37, + 0xf1, 0xa2, 0x1f, 0x31, 0x23, 0x5f, 0x01, 0x58, 0xf6, 0xdc, 0xd0, 0xf7, 0x5a, 0xeb, 0xde, 0xee, + 0xfc, 0x08, 0x6a, 0x26, 0x9e, 0x4f, 0x0c, 0x40, 0x8c, 0xc0, 0x95, 0x13, 0x91, 0xfa, 0xad, 0xc1, + 0x0b, 0xac, 0x96, 0xb7, 0xab, 0xae, 0x83, 0x18, 0x9f, 0xdc, 0x82, 0x92, 0x54, 0xfb, 0x6c, 0x75, + 0x76, 0x7d, 0x9c, 0x20, 0xa3, 0xb1, 0x5c, 0x48, 0x9f, 0x84, 0x56, 0x57, 0xc0, 0xb5, 0x73, 0x33, + 0x41, 0x43, 0xbe, 0x0c, 0x67, 0x92, 0x30, 0x39, 0xca, 0xc5, 0xf8, 0xc6, 0xa4, 0xb2, 0xcb, 0x98, + 0xf7, 0xbd, 0x58, 0x90, 0xdb, 0x30, 0xcd, 0x3a, 0x64, 0x83, 0xda, 0x41, 0x97, 0x5b, 0xed, 0x09, + 0xc5, 0x99, 0x7c, 0xef, 0x16, 0xab, 0xb0, 0xe5, 0x35, 0xf6, 0x15, 0x24, 0x33, 0x49, 0x45, 0x6e, + 0xc2, 0x38, 0x37, 0xc3, 0xf0, 0xab, 0xee, 0x8e, 0x27, 0x5e, 0x45, 0xe4, 0x63, 0x81, 0x28, 0x79, + 0xb0, 0xc8, 0xca, 0x4c, 0x15, 0xd1, 0x38, 0xcc, 0xc3, 0xe9, 0xec, 0x3a, 0xc8, 0x9f, 0x87, 0x53, + 0xa2, 0x3f, 0x5b, 0xd4, 0x57, 0x70, 0x06, 0x30, 0x50, 0xb9, 0x22, 0xc6, 0xe9, 0x85, 0x46, 0xc4, + 0x20, 0xda, 0x70, 0x18, 0x8b, 0xc4, 0xa4, 0xc8, 0xae, 0x87, 0x7c, 0x0d, 0xc6, 0xd5, 0x6a, 0xf3, + 0x83, 0xdb, 0xfa, 0xf4, 0xa9, 0x4b, 0x65, 0x49, 0x6c, 0x98, 0x36, 0xe9, 0xd7, 0xbb, 0x34, 0x08, + 0xa5, 0xb5, 0x91, 0x90, 0x58, 0xce, 0xa6, 0x6a, 0x91, 0x08, 0x91, 0x56, 0xaf, 0xe4, 0x73, 0x4a, + 0x4b, 0xda, 0x84, 0x7e, 0x9b, 0xb1, 0x4f, 0xf2, 0x33, 0xbe, 0x97, 0x87, 0x33, 0x3d, 0xa6, 0x33, + 0xdb, 0xf1, 0x14, 0xc9, 0x10, 0x77, 0xbc, 0x84, 0x40, 0xc8, 0x4d, 0x15, 0x2f, 0x40, 0x5e, 0x48, + 0x60, 0x43, 0x4b, 0xa5, 0xa3, 0xc3, 0xf2, 0x84, 0xb6, 0x52, 0xf3, 0xd5, 0x15, 0x72, 0x07, 0x86, + 0x58, 0x37, 0x0c, 0x60, 0x71, 0x23, 0x75, 0xba, 0x53, 0xa1, 0xa3, 0x6e, 0x10, 0xd8, 0x37, 0xc8, + 0x83, 0x7c, 0x16, 0x0a, 0x9b, 0x9b, 0xeb, 0xb8, 0x3b, 0x14, 0x70, 0x76, 0x4f, 0x86, 0x61, 0x4b, + 0xdb, 0x8c, 0x26, 0x19, 0x6d, 0xd4, 0x23, 0x26, 0x43, 0x27, 0x1f, 0x24, 0x2c, 0x01, 0x5f, 0xed, + 0xbf, 0x94, 0x07, 0x37, 0x0c, 0xfc, 0x18, 0xf6, 0x78, 0xc6, 0xb7, 0x72, 0xd2, 0xe8, 0x49, 0x4c, + 0x7e, 0x72, 0x41, 0xae, 0x13, 0xd4, 0x3b, 0x08, 0x2e, 0x2a, 0x88, 0x3c, 0x0f, 0xc0, 0x7f, 0x6e, + 0x6d, 0x89, 0x4e, 0x9f, 0x30, 0x15, 0x08, 0x79, 0x33, 0x62, 0x29, 0x34, 0xb5, 0x05, 0x94, 0x04, + 0x12, 0x6b, 0x8d, 0x97, 0x99, 0x3a, 0xaa, 0xf1, 0x1b, 0xf9, 0xf8, 0xd4, 0xb8, 0xe5, 0xb4, 0x42, + 0xea, 0x93, 0x05, 0x7e, 0x08, 0xc4, 0x97, 0x35, 0x33, 0xfa, 0x4d, 0xe6, 0xe3, 0x13, 0x85, 0x37, + 0x2d, 0x3a, 0x3a, 0x5e, 0x55, 0x8e, 0x8e, 0x02, 0x1e, 0x1d, 0x53, 0x3d, 0x0f, 0x89, 0x57, 0x33, + 0x76, 0x42, 0xdc, 0xfa, 0x33, 0x76, 0xbb, 0x97, 0x60, 0xf2, 0x9e, 0xb7, 0xfa, 0x24, 0x8c, 0x10, + 0xd9, 0x96, 0x5f, 0x34, 0x75, 0x20, 0xe3, 0x78, 0xbf, 0xd5, 0xa4, 0xfe, 0xe6, 0x9e, 0xed, 0x6a, + 0xb6, 0x33, 0x66, 0x0a, 0xce, 0x70, 0xef, 0xd1, 0xc7, 0x3a, 0xee, 0x28, 0xc7, 0x4d, 0xc2, 0x93, + 0x83, 0x53, 0x4c, 0x0d, 0x8e, 0xf1, 0x17, 0xf3, 0xb2, 0xbb, 0x1e, 0x2c, 0x3e, 0xa3, 0x56, 0x15, + 0xaf, 0x6b, 0x56, 0x15, 0xb3, 0xd1, 0x7b, 0x50, 0x64, 0x92, 0xb4, 0x98, 0x25, 0x70, 0x28, 0x26, + 0x11, 0xbf, 0x34, 0x02, 0x13, 0x2a, 0x3a, 0xeb, 0x87, 0x4a, 0xb3, 0xe9, 0xab, 0xfd, 0x60, 0x37, + 0x9b, 0xbe, 0x89, 0x50, 0xcd, 0x70, 0xa9, 0xd0, 0xd7, 0x70, 0xe9, 0xab, 0x30, 0xb6, 0xdc, 0x6e, + 0x6a, 0xe6, 0x0d, 0x46, 0xc6, 0xe7, 0x5d, 0x8d, 0x90, 0xf8, 0xea, 0x8d, 0x9e, 0x39, 0x1a, 0xed, + 0x66, 0xda, 0xa8, 0x21, 0x66, 0xa9, 0xd9, 0x3c, 0x0d, 0x7f, 0x1c, 0x9b, 0xa7, 0x9b, 0x30, 0xb6, + 0x15, 0xd0, 0xcd, 0xae, 0xeb, 0xd2, 0x16, 0x4e, 0xbc, 0x22, 0xd7, 0x0e, 0x74, 0x03, 0x6a, 0x85, + 0x08, 0x55, 0x3f, 0x20, 0x42, 0x55, 0x07, 0x78, 0xb4, 0xcf, 0x00, 0xdf, 0x80, 0x62, 0x8d, 0x52, + 0x1f, 0xfb, 0x74, 0x3c, 0xbe, 0x25, 0x75, 0x28, 0xf5, 0x2d, 0xd6, 0xb1, 0x9a, 0x2d, 0x94, 0x40, + 0xd4, 0x0c, 0xa8, 0x26, 0x06, 0x34, 0xa0, 0x22, 0x2f, 0xc0, 0x44, 0xa7, 0xbb, 0xdd, 0x72, 0x1a, + 0xc8, 0x57, 0x58, 0x5e, 0x99, 0xe3, 0x1c, 0xc6, 0xd8, 0x06, 0xe4, 0x03, 0x98, 0x44, 0xad, 0x48, + 0x34, 0xe5, 0xa6, 0xb4, 0xa3, 0x5d, 0x2b, 0xe3, 0xd2, 0x77, 0x83, 0x81, 0xac, 0x0c, 0x3b, 0x43, + 0x9d, 0x11, 0xb9, 0x03, 0xa3, 0xbb, 0x4e, 0x68, 0xed, 0x75, 0xb7, 0xe7, 0xa7, 0x35, 0x23, 0xbd, + 0xdb, 0x4e, 0xb8, 0xd6, 0xdd, 0xe6, 0x43, 0x1e, 0xb1, 0xc6, 0x3d, 0x7a, 0xd7, 0x09, 0xf7, 0xba, + 0xaa, 0xe2, 0x63, 0x64, 0x17, 0x71, 0x17, 0xea, 0x30, 0xa5, 0xcf, 0x8a, 0xa7, 0x60, 0x5a, 0x10, + 0x19, 0x96, 0x15, 0x4b, 0x63, 0x77, 0x86, 0x8a, 0x50, 0x1a, 0xe7, 0x26, 0x65, 0x26, 0xd4, 0xa2, + 0xfe, 0x31, 0xc9, 0xdd, 0xee, 0x36, 0xf5, 0x5d, 0x1a, 0xd2, 0x40, 0xdc, 0xd1, 0x03, 0x73, 0xa8, + 0xd2, 0xe9, 0x04, 0xc6, 0xdf, 0xcf, 0xc3, 0x68, 0xe5, 0x61, 0x1d, 0x77, 0xfd, 0xd7, 0xd4, 0x77, + 0x61, 0xd5, 0x40, 0x20, 0x7a, 0x17, 0x56, 0x5f, 0x83, 0xaf, 0x65, 0x28, 0x91, 0xd0, 0xf5, 0x41, + 0x51, 0x22, 0x69, 0xaa, 0xa3, 0xf8, 0x89, 0xbc, 0x30, 0xc0, 0x13, 0x79, 0xf4, 0x8a, 0x31, 0x74, + 0xfc, 0x2b, 0xc6, 0x5b, 0x30, 0x5e, 0x75, 0x43, 0xba, 0xeb, 0xc7, 0xab, 0x26, 0x52, 0x68, 0x45, + 0x60, 0xf5, 0xe6, 0xad, 0x60, 0xb3, 0x29, 0xc9, 0x5f, 0x4e, 0xa2, 0x17, 0x13, 0x9c, 0x92, 0xfc, + 0x81, 0x25, 0xa1, 0x8d, 0x94, 0x88, 0xc6, 0x4a, 0x62, 0xbe, 0x49, 0x33, 0xa4, 0x9c, 0xae, 0x13, + 0xe3, 0x1d, 0xbb, 0x34, 0x93, 0x6d, 0x86, 0x64, 0xfc, 0x95, 0x1c, 0xcc, 0x65, 0x4d, 0x23, 0xf2, + 0x2e, 0x4c, 0x78, 0xfe, 0xae, 0xed, 0x3a, 0x3f, 0xc8, 0x5b, 0xa4, 0xa8, 0xcc, 0x55, 0xb8, 0xaa, + 0x13, 0x53, 0xe1, 0xac, 0x43, 0x94, 0x96, 0xeb, 0x1a, 0xbe, 0xcc, 0x0e, 0x51, 0xc0, 0xc6, 0x8f, + 0xe4, 0x61, 0xbc, 0xd2, 0xe9, 0x3c, 0xe3, 0x96, 0xb5, 0x9f, 0xd7, 0x0e, 0x10, 0xa9, 0x81, 0x88, + 0xda, 0xd5, 0xdb, 0x2e, 0x4f, 0x39, 0x43, 0xfe, 0x6e, 0x1e, 0xa6, 0x13, 0x14, 0xea, 0xd7, 0xe7, + 0x06, 0x34, 0x84, 0xcd, 0x0f, 0x68, 0x08, 0x5b, 0x18, 0xcc, 0x10, 0x76, 0xe8, 0xe3, 0x1c, 0x0a, + 0xaf, 0x40, 0xa1, 0xd2, 0xe9, 0x24, 0x0d, 0x5c, 0x3a, 0x9d, 0x07, 0x37, 0xb8, 0x12, 0xcc, 0xee, + 0x74, 0x4c, 0x86, 0xa1, 0xed, 0xd4, 0x23, 0x03, 0xee, 0xd4, 0xc6, 0x15, 0x18, 0x43, 0x5e, 0x68, + 0x0e, 0x7a, 0x01, 0x70, 0x8b, 0x11, 0x96, 0xa0, 0x5a, 0x5d, 0x62, 0xf3, 0xf9, 0xe3, 0x1c, 0x0c, + 0xe3, 0xef, 0x67, 0x74, 0x8e, 0x2d, 0x6a, 0x73, 0xac, 0xa4, 0xcc, 0xb1, 0x41, 0x66, 0xd7, 0xdf, + 0x2e, 0x00, 0x2c, 0xdf, 0x37, 0xeb, 0x5c, 0x57, 0x4a, 0x6e, 0xc1, 0xb4, 0xdd, 0x6a, 0x79, 0x8f, + 0x69, 0xd3, 0xf2, 0x7c, 0x67, 0xd7, 0x71, 0x79, 0xcf, 0x49, 0xab, 0x0b, 0xbd, 0x48, 0x7d, 0x8b, + 0x15, 0x45, 0xf7, 0x79, 0x89, 0xca, 0xa7, 0x4d, 0xc3, 0x3d, 0xaf, 0x29, 0xd5, 0x26, 0x1a, 0x1f, + 0x51, 0x94, 0xc1, 0x67, 0x83, 0x97, 0xa8, 0x7c, 0xf6, 0x50, 0x0d, 0x24, 0x65, 0x68, 0x8d, 0x8f, + 0x28, 0xca, 0xe0, 0xc3, 0x75, 0x47, 0x01, 0x59, 0x07, 0x7c, 0x0a, 0x78, 0x6c, 0x35, 0x7c, 0xda, + 0xa4, 0x6e, 0xe8, 0xd8, 0xad, 0x40, 0x28, 0xda, 0x50, 0xa3, 0x9c, 0x2a, 0x54, 0x15, 0x0d, 0x58, + 0xb8, 0x1c, 0x97, 0x91, 0xab, 0x30, 0xda, 0xb6, 0x9f, 0x58, 0xf6, 0x2e, 0xb7, 0x3f, 0x9a, 0xe4, + 0x8a, 0x19, 0x01, 0x52, 0x8f, 0x91, 0xb6, 0xfd, 0xa4, 0xb2, 0x4b, 0x59, 0x2b, 0xe8, 0x93, 0x8e, + 0x17, 0x28, 0xad, 0x18, 0x89, 0x5b, 0x91, 0x28, 0x52, 0x5b, 0x21, 0x8a, 0x44, 0x2b, 0x8c, 0x5f, + 0xc9, 0xc1, 0xb9, 0x2a, 0x7e, 0x45, 0x78, 0xb0, 0x4c, 0xdd, 0x90, 0xfa, 0x35, 0xea, 0xb7, 0x1d, + 0xb4, 0xc6, 0xa8, 0xd3, 0x90, 0xbc, 0x08, 0x85, 0x8a, 0x79, 0x4f, 0xcc, 0x5f, 0xbe, 0xdf, 0x6b, + 0xb6, 0x31, 0xac, 0x34, 0xd2, 0xdd, 0xe5, 0x8f, 0x79, 0x53, 0xa8, 0xc0, 0x44, 0x25, 0x08, 0x9c, + 0x5d, 0xb7, 0xcd, 0xdd, 0x91, 0x0a, 0x9a, 0xf5, 0x8d, 0x80, 0xa7, 0xde, 0xfa, 0x54, 0x12, 0xe3, + 0xbf, 0xce, 0xc1, 0x4c, 0xa5, 0xd3, 0xd1, 0x3f, 0x59, 0xb7, 0xfc, 0xca, 0x0d, 0x6e, 0xf9, 0xe5, + 0xc0, 0x94, 0xd6, 0x5c, 0x3e, 0xa5, 0x62, 0xc1, 0xb7, 0x4f, 0xcf, 0xf0, 0xcf, 0xee, 0x44, 0x20, + 0x2b, 0xd0, 0xcd, 0x16, 0x12, 0x8c, 0x8d, 0xff, 0xb2, 0x88, 0x7b, 0x88, 0xd8, 0x6d, 0x85, 0x6d, + 0x72, 0x2e, 0xc3, 0x36, 0xf9, 0x0d, 0x50, 0x24, 0x1c, 0xf5, 0x88, 0x53, 0x64, 0x45, 0x55, 0xeb, + 0x15, 0x23, 0x93, 0xfd, 0xa4, 0x95, 0x72, 0x01, 0x5b, 0xf3, 0x62, 0x72, 0x01, 0x3f, 0x15, 0x03, + 0xe5, 0x35, 0x20, 0x55, 0x17, 0x4d, 0x29, 0x68, 0x7d, 0xdf, 0xe9, 0x3c, 0xa0, 0xbe, 0xb3, 0x73, + 0x20, 0x16, 0x00, 0x76, 0xbe, 0x23, 0x4a, 0xad, 0x60, 0xdf, 0xe9, 0x58, 0x8f, 0xb0, 0xdc, 0xcc, + 0xa0, 0x21, 0xef, 0xc1, 0xa8, 0x49, 0x1f, 0xfb, 0x4e, 0x28, 0x6d, 0xef, 0xa6, 0x22, 0x25, 0x2e, + 0x42, 0xf9, 0x5a, 0xf0, 0xf9, 0x0f, 0x75, 0x57, 0x14, 0xe5, 0x64, 0x91, 0x0b, 0x29, 0xdc, 0xc6, + 0x6e, 0x32, 0x6e, 0x6d, 0xe5, 0x61, 0xbd, 0x97, 0x8c, 0x42, 0x2e, 0xc3, 0x30, 0x4a, 0x3a, 0xe2, + 0x2e, 0x80, 0xae, 0x76, 0x28, 0x3b, 0xab, 0x62, 0x18, 0x62, 0xa0, 0x4e, 0x40, 0xda, 0x2a, 0x04, + 0xf3, 0x45, 0x94, 0xd2, 0x15, 0x48, 0x52, 0x4c, 0x1b, 0x3b, 0x91, 0x98, 0xb6, 0x0e, 0x25, 0x93, + 0x7b, 0xed, 0x36, 0x2b, 0x1d, 0x7c, 0x10, 0x0f, 0xe6, 0x01, 0x57, 0xf2, 0x85, 0xa3, 0xc3, 0xf2, + 0x73, 0xc2, 0xa3, 0xb7, 0x69, 0xd9, 0x1d, 0xfe, 0x8e, 0xae, 0x6d, 0x23, 0x49, 0x4a, 0xf2, 0x06, + 0x0c, 0xb1, 0xad, 0x57, 0xd8, 0x33, 0xcb, 0x97, 0xb7, 0x78, 0x37, 0xe6, 0x8b, 0xb3, 0xe1, 0x69, + 0x7b, 0x02, 0x92, 0x10, 0x0b, 0xa6, 0xf4, 0xe9, 0x2e, 0x4c, 0xdb, 0xe6, 0xe3, 0xfe, 0xd4, 0xcb, + 0xc5, 0x73, 0x9c, 0x80, 0x59, 0x0d, 0x04, 0xaa, 0x2b, 0x20, 0xb1, 0x48, 0x57, 0xa1, 0xb8, 0xb9, + 0x5c, 0xab, 0x79, 0x7e, 0xc8, 0xaf, 0x3a, 0xf1, 0xc9, 0xc2, 0x60, 0xa6, 0xed, 0xee, 0x52, 0x7e, + 0x16, 0x87, 0x8d, 0x8e, 0xd5, 0x61, 0x68, 0xea, 0x59, 0x2c, 0x49, 0xc9, 0x57, 0xe0, 0xd4, 0x56, + 0x40, 0x2b, 0xee, 0x01, 0x9e, 0xce, 0xca, 0x52, 0x99, 0xc2, 0xa9, 0x87, 0x0f, 0x4a, 0xec, 0x2a, + 0x68, 0xbb, 0x07, 0x16, 0x3f, 0xd5, 0xb3, 0x17, 0x4e, 0x36, 0x17, 0x72, 0x0d, 0x0a, 0x1b, 0xcb, + 0x35, 0x71, 0x27, 0x92, 0x96, 0xa7, 0x1b, 0xcb, 0x35, 0x3e, 0x91, 0xda, 0xba, 0xd9, 0xfc, 0xc6, + 0x72, 0xed, 0x93, 0xb3, 0xad, 0xfe, 0x32, 0x7e, 0x09, 0x99, 0x87, 0xd1, 0x06, 0xc7, 0x11, 0xdc, + 0xe4, 0x4f, 0x42, 0x60, 0xc8, 0xf6, 0x77, 0xc5, 0x31, 0x68, 0xe2, 0xdf, 0xe4, 0x15, 0x28, 0xf9, + 0x5d, 0xd7, 0xb2, 0x03, 0xfe, 0x34, 0xd7, 0x0d, 0xa8, 0xcf, 0xb7, 0x59, 0x73, 0xd2, 0xef, 0xba, + 0x95, 0x80, 0xc9, 0x5d, 0x68, 0x07, 0xfd, 0x0f, 0x72, 0xa0, 0xac, 0x9f, 0xa2, 0x49, 0x9b, 0x8e, + 0x4f, 0x1b, 0xa1, 0x38, 0x9b, 0x85, 0x9f, 0x2c, 0x87, 0x25, 0x2c, 0x74, 0x11, 0x46, 0xde, 0x85, + 0x51, 0x71, 0x86, 0x88, 0x3d, 0x53, 0xae, 0x3b, 0xf1, 0xe2, 0xc2, 0x1d, 0xaa, 0x53, 0xe7, 0x8f, + 0x24, 0x62, 0x5b, 0xf6, 0x9d, 0x87, 0x9b, 0xcb, 0x2d, 0xdb, 0x69, 0x07, 0xe2, 0x20, 0xc0, 0x5d, + 0xe3, 0xc3, 0xc7, 0xa1, 0xd5, 0x40, 0xa8, 0xba, 0x65, 0x47, 0xa8, 0xc6, 0x6d, 0xf9, 0xe0, 0x73, + 0x8c, 0x99, 0x79, 0x19, 0x86, 0x1f, 0xc4, 0x6a, 0xc1, 0xa5, 0xb1, 0xa3, 0xc3, 0x32, 0xef, 0x5b, + 0x93, 0xc3, 0x0d, 0x0a, 0x63, 0xd1, 0xbc, 0x63, 0xbc, 0xd8, 0x0f, 0xe4, 0x35, 0xc9, 0x79, 0xb1, + 0x19, 0x68, 0x22, 0x94, 0xc9, 0x69, 0xab, 0x6e, 0x13, 0x11, 0xf2, 0x88, 0x80, 0xdd, 0x43, 0xdd, + 0x26, 0x4e, 0x53, 0xb5, 0x75, 0x02, 0x4d, 0x91, 0x86, 0x7e, 0x2c, 0x07, 0x53, 0xfa, 0x18, 0x93, + 0xab, 0x30, 0x22, 0x5c, 0x61, 0x73, 0xa8, 0x65, 0x65, 0xdc, 0x46, 0xb8, 0x13, 0xac, 0xe6, 0xfa, + 0x2a, 0xb0, 0x98, 0xd0, 0x27, 0x38, 0x08, 0x89, 0x07, 0x85, 0x3e, 0x31, 0x0b, 0x4c, 0x59, 0x46, + 0x0c, 0x76, 0x0f, 0x0d, 0xba, 0xad, 0x50, 0x7d, 0x1d, 0xf6, 0x11, 0x62, 0x8a, 0x12, 0xe3, 0x3b, + 0x39, 0x18, 0xe1, 0x1b, 0x63, 0xc2, 0x8c, 0x36, 0x77, 0x12, 0x33, 0xda, 0x6f, 0xc0, 0x9c, 0xe9, + 0xb5, 0x68, 0x50, 0x71, 0x0f, 0x1e, 0xef, 0x51, 0x9f, 0xd6, 0x7c, 0x6f, 0x47, 0x3e, 0x64, 0x8f, + 0x2f, 0xbe, 0xa0, 0x6d, 0xc0, 0x59, 0x88, 0xfc, 0x25, 0xd2, 0x67, 0x25, 0x6c, 0x99, 0x62, 0x11, + 0x5b, 0xab, 0x89, 0x87, 0xef, 0xcc, 0x4a, 0x8c, 0xbf, 0x93, 0x83, 0x85, 0xde, 0xac, 0xf1, 0xf8, + 0xe4, 0x7f, 0xc6, 0x72, 0x0b, 0x3f, 0x3e, 0x39, 0x34, 0x61, 0xdb, 0xab, 0x20, 0x13, 0x13, 0x4e, + 0x55, 0x1a, 0x0d, 0xda, 0x09, 0x19, 0x63, 0x61, 0x91, 0x1a, 0xc9, 0x35, 0x45, 0xae, 0x5e, 0xb1, + 0x11, 0x81, 0x5b, 0x09, 0x4b, 0x3b, 0x59, 0x9c, 0x75, 0xd9, 0xa4, 0xc6, 0xbf, 0xcd, 0x01, 0xd4, + 0xeb, 0x6b, 0x77, 0xe9, 0x41, 0xcd, 0x76, 0x50, 0x50, 0xe1, 0x7b, 0xcd, 0x5d, 0xb1, 0x39, 0x4c, + 0x08, 0xcb, 0x16, 0xbe, 0x45, 0xed, 0xd3, 0x03, 0xcd, 0xb2, 0x45, 0xa2, 0xf2, 0x56, 0x39, 0x8f, + 0xec, 0x90, 0x32, 0x42, 0x54, 0x4b, 0xcb, 0x56, 0x21, 0x34, 0x41, 0xa9, 0x20, 0x93, 0xaf, 0xc0, + 0x54, 0xfc, 0x2b, 0xb2, 0xcf, 0x99, 0x8a, 0x36, 0x20, 0xbd, 0x70, 0xe9, 0xf9, 0xa3, 0xc3, 0xf2, + 0x82, 0xc2, 0x35, 0x69, 0xa4, 0x92, 0x60, 0xf6, 0xe6, 0xd0, 0xff, 0xf6, 0x0b, 0xe5, 0x1c, 0x1a, + 0x51, 0x6d, 0xae, 0xd7, 0x65, 0x33, 0x2f, 0xc2, 0x50, 0xe4, 0x4d, 0x31, 0x21, 0xce, 0x1c, 0xfd, + 0xad, 0x1b, 0xcb, 0x99, 0x74, 0x19, 0xb7, 0x07, 0x37, 0x58, 0xbd, 0x1d, 0xac, 0x94, 0xdc, 0x86, + 0xd1, 0x81, 0xbe, 0x1c, 0x17, 0x65, 0xc6, 0x17, 0x4b, 0x6a, 0x26, 0x74, 0x2d, 0x9b, 0xfc, 0x69, + 0x63, 0x82, 0x0b, 0x5d, 0x0d, 0xbf, 0x65, 0x32, 0x98, 0x71, 0x98, 0x03, 0xb8, 0xf3, 0x70, 0xf3, + 0xfb, 0x76, 0x98, 0x8c, 0x9f, 0xca, 0xc3, 0x4c, 0x6c, 0x0f, 0x29, 0xdb, 0xf9, 0x39, 0x80, 0xb8, + 0x49, 0xc7, 0x37, 0xb4, 0x13, 0x35, 0xf4, 0x4d, 0x18, 0x57, 0x2a, 0x1f, 0xa0, 0xa5, 0x9d, 0xb8, + 0xa5, 0x16, 0x94, 0x92, 0x1f, 0xfe, 0x31, 0xdb, 0xda, 0xd1, 0xf0, 0xd9, 0xec, 0xdb, 0xb3, 0x03, + 0x6e, 0x7e, 0x3c, 0xc9, 0x67, 0x1f, 0xfb, 0xad, 0xce, 0x3e, 0xf6, 0xdb, 0xa8, 0x40, 0xa9, 0xb2, + 0x4b, 0xb5, 0x5e, 0x21, 0x57, 0x32, 0x7a, 0x04, 0x95, 0x85, 0x31, 0x54, 0xe9, 0x07, 0xe3, 0x27, + 0xf2, 0x30, 0xcd, 0x66, 0x72, 0xa5, 0x1b, 0xee, 0x79, 0xbe, 0x13, 0x1e, 0x3c, 0xb3, 0x0f, 0x13, + 0x6f, 0x6b, 0x77, 0xfe, 0x05, 0x29, 0x9d, 0xa8, 0x6d, 0x1b, 0xe8, 0x7d, 0xe2, 0x7f, 0x18, 0x86, + 0xd9, 0x0c, 0x2a, 0xf2, 0x9a, 0xf6, 0xda, 0x39, 0x2f, 0xc3, 0xb1, 0x7c, 0xef, 0xb0, 0x3c, 0x21, + 0xd1, 0x37, 0xe3, 0xf0, 0x2c, 0x8b, 0xba, 0x69, 0x2d, 0xef, 0x29, 0x7c, 0xfc, 0x54, 0x4d, 0x6b, + 0x75, 0x83, 0xda, 0xcb, 0x30, 0x8c, 0x27, 0x82, 0x30, 0x27, 0x47, 0x89, 0x1e, 0xcf, 0x18, 0xcd, + 0xbe, 0x8c, 0x01, 0xc8, 0x1a, 0x8c, 0xb2, 0x3f, 0x36, 0xec, 0x8e, 0x30, 0x3d, 0x20, 0x91, 0xd6, + 0x09, 0xa1, 0x1d, 0xc7, 0xdd, 0x55, 0x15, 0x4f, 0x2d, 0x6a, 0xb5, 0xed, 0x8e, 0x76, 0xf5, 0xe0, + 0x88, 0x9a, 0x02, 0xab, 0xd8, 0x5b, 0x81, 0x95, 0x3b, 0x56, 0x81, 0xb5, 0x03, 0x50, 0x77, 0x76, + 0x5d, 0xc7, 0xdd, 0xad, 0xb4, 0x76, 0x45, 0x50, 0x9b, 0xcb, 0xbd, 0x47, 0xe1, 0x6a, 0x8c, 0x8c, + 0x6b, 0xe4, 0x1c, 0xda, 0x07, 0x71, 0x98, 0x65, 0xb7, 0x76, 0x35, 0x2f, 0x56, 0x85, 0x33, 0xb9, + 0x07, 0x50, 0x69, 0x84, 0xce, 0x23, 0xb6, 0x5a, 0x02, 0x71, 0x4f, 0x90, 0x9f, 0xbc, 0x5c, 0xb9, + 0x4b, 0x0f, 0xf0, 0x6e, 0x2b, 0x2d, 0x2d, 0x6c, 0x44, 0x65, 0xb3, 0x5e, 0x73, 0x51, 0x8c, 0x39, + 0x90, 0x0e, 0x9c, 0xaa, 0x34, 0x9b, 0x0e, 0x6b, 0x83, 0xdd, 0xda, 0xe4, 0xe1, 0x88, 0x90, 0xf5, + 0x44, 0x36, 0xeb, 0xcb, 0xd2, 0x38, 0xc0, 0x8e, 0xa8, 0x2c, 0x19, 0xc5, 0x28, 0x51, 0x4d, 0x36, + 0x63, 0xa3, 0x0e, 0x53, 0x7a, 0xe3, 0xf5, 0x60, 0x3c, 0x13, 0x50, 0x34, 0xeb, 0x15, 0xab, 0xbe, + 0x56, 0xb9, 0x5e, 0xca, 0x91, 0x12, 0x4c, 0x88, 0x5f, 0x8b, 0xd6, 0xe2, 0xeb, 0x37, 0x4b, 0x79, + 0x0d, 0xf2, 0xfa, 0xf5, 0xc5, 0x52, 0x61, 0x21, 0x3f, 0x9f, 0x4b, 0x38, 0xb0, 0x8f, 0x96, 0x8a, + 0xfc, 0xcd, 0xc1, 0xf8, 0xd5, 0x1c, 0x14, 0xe5, 0xb7, 0x93, 0x9b, 0x50, 0xa8, 0xd7, 0xd7, 0x12, + 0x2e, 0xe0, 0xf1, 0xe9, 0xce, 0x4f, 0xb0, 0x40, 0xdb, 0x69, 0x18, 0x01, 0xa3, 0xdb, 0x5c, 0xaf, + 0x0b, 0x39, 0x59, 0xd2, 0xc5, 0xc7, 0x25, 0xa7, 0xcb, 0xf0, 0x8b, 0xbd, 0x09, 0x85, 0x3b, 0x0f, + 0x37, 0xc5, 0x2d, 0x5e, 0xd2, 0xc5, 0xc7, 0x14, 0xa7, 0xfb, 0xf0, 0xb1, 0x7a, 0xae, 0x32, 0x02, + 0xc3, 0x84, 0x71, 0x65, 0x22, 0x73, 0xc1, 0xb0, 0xed, 0x45, 0x11, 0x68, 0x84, 0x60, 0xc8, 0x20, + 0xa6, 0x28, 0x61, 0xe2, 0xf2, 0xba, 0xd7, 0xb0, 0x5b, 0x42, 0xc2, 0x44, 0x71, 0xb9, 0xc5, 0x00, + 0x26, 0x87, 0x1b, 0xbf, 0x99, 0x83, 0x52, 0xcd, 0xf7, 0x78, 0x94, 0x9c, 0x4d, 0x6f, 0x9f, 0xba, + 0x0f, 0xae, 0x93, 0x2b, 0x72, 0xc9, 0xe5, 0x22, 0x4d, 0xea, 0x30, 0x2e, 0xb9, 0xc4, 0x73, 0xb4, + 0x58, 0x76, 0x4a, 0x90, 0x9f, 0xfc, 0xe0, 0xc1, 0x41, 0x8e, 0x09, 0xf2, 0x53, 0x86, 0x61, 0xfc, + 0x1c, 0xb1, 0x39, 0xe2, 0x97, 0x87, 0x0c, 0x60, 0x72, 0xb8, 0xb2, 0x37, 0x1d, 0xe6, 0x53, 0x6d, + 0x58, 0xfc, 0xbe, 0x0a, 0xb0, 0xa1, 0x37, 0xae, 0xf7, 0x7e, 0x4d, 0xee, 0xf6, 0x08, 0xb0, 0x91, + 0x60, 0xc0, 0xfd, 0x63, 0x17, 0xf9, 0x2b, 0x15, 0xf7, 0x32, 0x53, 0x75, 0x91, 0x29, 0x7f, 0xfd, + 0x2f, 0xc2, 0x5c, 0xb2, 0x7f, 0x51, 0x65, 0x5e, 0x81, 0x69, 0x1d, 0x2e, 0xb5, 0xe7, 0x67, 0x32, + 0xeb, 0x7d, 0xb0, 0x68, 0x26, 0xf1, 0x8d, 0x7f, 0x93, 0x83, 0x31, 0xfc, 0xd3, 0xec, 0x72, 0x29, + 0xbf, 0xf2, 0xb0, 0x2e, 0x14, 0x79, 0xaa, 0x94, 0x6f, 0x3f, 0x0e, 0xa4, 0x85, 0xa7, 0xb6, 0x61, + 0x45, 0xc8, 0x82, 0x94, 0xbf, 0xc6, 0x49, 0x15, 0x72, 0x44, 0xca, 0x9f, 0xed, 0x82, 0x04, 0xa9, + 0x40, 0x46, 0x97, 0x0d, 0x7e, 0xed, 0x50, 0xed, 0xed, 0x90, 0xce, 0x6b, 0xe9, 0x2e, 0x1b, 0x1c, + 0x0d, 0xcd, 0xed, 0x1e, 0xd6, 0xd9, 0x4d, 0x44, 0x35, 0xb7, 0x63, 0xdf, 0xa8, 0xdd, 0x42, 0x04, + 0x92, 0xf1, 0x8f, 0x26, 0x93, 0x1d, 0x28, 0x4e, 0xcf, 0x13, 0x2e, 0xb4, 0xb7, 0x60, 0xb8, 0xd2, + 0x6a, 0x79, 0x8f, 0xc5, 0x96, 0x23, 0xf5, 0x2c, 0x51, 0xff, 0xf1, 0xc3, 0x11, 0x95, 0xd0, 0x9a, + 0x2b, 0x3f, 0x03, 0x90, 0x65, 0x18, 0xab, 0x3c, 0xac, 0x57, 0xab, 0x2b, 0x9b, 0x9b, 0xdc, 0x6d, + 0xb9, 0xb0, 0xf4, 0xb2, 0xec, 0x1f, 0xc7, 0x69, 0x5a, 0x49, 0x7b, 0xa0, 0xf8, 0xc2, 0x1a, 0xd3, + 0x91, 0x77, 0x00, 0xee, 0x78, 0x8e, 0xcb, 0x95, 0xee, 0xa2, 0xf1, 0xe7, 0x8f, 0x0e, 0xcb, 0xe3, + 0x1f, 0x7a, 0x8e, 0x2b, 0xb4, 0xf4, 0xec, 0xdb, 0x63, 0x24, 0x53, 0xf9, 0x9b, 0xf5, 0xf4, 0x92, + 0xc7, 0xed, 0x84, 0x87, 0xe3, 0x9e, 0xde, 0xf6, 0x52, 0xda, 0x61, 0x89, 0x46, 0xda, 0x30, 0x5d, + 0xef, 0xee, 0xee, 0x52, 0x76, 0x4c, 0x08, 0xed, 0xe7, 0x88, 0x50, 0xb4, 0x44, 0x31, 0xee, 0xf8, + 0x05, 0x9c, 0xdd, 0xfe, 0x83, 0xa5, 0xd7, 0xd8, 0xaa, 0xf8, 0xee, 0x61, 0x59, 0xd8, 0x19, 0x31, + 0x11, 0x33, 0x90, 0xf4, 0x69, 0xdd, 0x67, 0x92, 0x37, 0xb9, 0x0f, 0x23, 0xfc, 0x85, 0x53, 0xb8, + 0xe1, 0xbe, 0xd0, 0x67, 0x05, 0x72, 0xc4, 0x5e, 0x6f, 0xe8, 0xbc, 0x94, 0x3c, 0x84, 0xe2, 0xb2, + 0xe3, 0x37, 0x5a, 0x74, 0xb9, 0x2a, 0x04, 0x89, 0x17, 0xfb, 0xb0, 0x94, 0xa8, 0xbc, 0x5f, 0x1a, + 0xf8, 0xab, 0xe1, 0xa8, 0x82, 0x85, 0xc4, 0x20, 0x7f, 0x25, 0x07, 0xe7, 0xa2, 0xaf, 0xaf, 0xec, + 0x52, 0x37, 0xdc, 0xb0, 0xc3, 0xc6, 0x1e, 0xf5, 0x45, 0x2f, 0x8d, 0xf5, 0xeb, 0xa5, 0x37, 0x53, + 0xbd, 0x74, 0x29, 0xee, 0x25, 0x9b, 0x31, 0xb3, 0xda, 0x9c, 0x5b, 0xba, 0xcf, 0xfa, 0xd5, 0x4a, + 0x2c, 0x80, 0xf8, 0xed, 0x5e, 0x18, 0x2c, 0xbe, 0xdc, 0xa7, 0xc1, 0x31, 0xb2, 0x70, 0xbf, 0x8c, + 0x7e, 0x6b, 0x06, 0xf6, 0x11, 0x94, 0xdc, 0x95, 0x3e, 0xef, 0x5c, 0xc4, 0xb9, 0xd0, 0x87, 0x37, + 0xf7, 0x83, 0x9f, 0xed, 0x13, 0xdd, 0x82, 0x8f, 0xf6, 0xba, 0xbd, 0x2d, 0xa4, 0x9a, 0x63, 0x46, + 0x7b, 0xdd, 0x8e, 0x47, 0xbb, 0x65, 0x27, 0x47, 0x7b, 0xdd, 0xde, 0x26, 0xcb, 0x3c, 0x50, 0x07, + 0x8f, 0xea, 0xf0, 0x7c, 0x3f, 0x6e, 0x52, 0xf3, 0x98, 0x11, 0xb0, 0xe3, 0x4b, 0x30, 0x56, 0xef, + 0xd8, 0x0d, 0xda, 0x72, 0x76, 0x42, 0x61, 0x18, 0xf2, 0x52, 0x1f, 0x56, 0x11, 0xae, 0x30, 0x04, + 0x90, 0x3f, 0xd5, 0x1b, 0x5e, 0x84, 0xc3, 0xbe, 0x70, 0xb3, 0xb6, 0x21, 0xf4, 0xa0, 0xfd, 0xbe, + 0x70, 0xb3, 0xb6, 0x21, 0x04, 0x98, 0x4e, 0x5b, 0x13, 0x60, 0x6a, 0x1b, 0xa4, 0x03, 0x53, 0x9b, + 0xd4, 0xf7, 0xed, 0x1d, 0xcf, 0x6f, 0x73, 0x6d, 0x3b, 0xf7, 0x14, 0xbe, 0xdc, 0x8f, 0x9f, 0x46, + 0xc0, 0x95, 0xcc, 0xa1, 0x84, 0x59, 0x49, 0x15, 0x7d, 0x82, 0x3f, 0xeb, 0x93, 0x25, 0x27, 0xdc, + 0xee, 0x36, 0xf6, 0x69, 0x38, 0x3f, 0x73, 0x6c, 0x9f, 0x44, 0xb8, 0xbc, 0x4f, 0xb6, 0xe5, 0x4f, + 0xb5, 0x4f, 0x22, 0x1c, 0x36, 0x0d, 0x44, 0x38, 0x0e, 0x72, 0xec, 0x34, 0xe0, 0x88, 0x7c, 0x1a, + 0xf4, 0x8a, 0xcb, 0x41, 0xf6, 0x60, 0x62, 0xc9, 0xeb, 0xba, 0x4c, 0xae, 0xed, 0xd8, 0x8e, 0x3f, + 0x3f, 0x8b, 0x6c, 0x5f, 0xe9, 0xf7, 0xc1, 0x0a, 0x3a, 0x77, 0xc3, 0xd8, 0x66, 0x10, 0x26, 0x3a, + 0x33, 0x90, 0xfa, 0x6e, 0xa6, 0xa2, 0x92, 0x26, 0x8c, 0xe3, 0x54, 0x5e, 0xa1, 0x8f, 0xbc, 0x4e, + 0x30, 0x3f, 0x87, 0x15, 0x5d, 0x3c, 0x6e, 0x51, 0x70, 0x6c, 0x6e, 0xa0, 0x81, 0x4b, 0xc3, 0x6a, + 0x22, 0x44, 0x7d, 0xcc, 0x50, 0x10, 0x8d, 0xbf, 0x3f, 0x0c, 0xe5, 0x63, 0x98, 0x91, 0x07, 0xf2, + 0x6c, 0xe2, 0x12, 0xc0, 0xa7, 0x07, 0xfb, 0x86, 0xab, 0xc7, 0x1e, 0x5b, 0x6f, 0xc1, 0xd4, 0x7d, + 0xc5, 0x56, 0x24, 0xb2, 0xdd, 0x41, 0x1a, 0xd5, 0x8a, 0xc4, 0x72, 0x9a, 0x66, 0x02, 0x75, 0xe1, + 0x8f, 0x0b, 0x30, 0x84, 0x82, 0xc5, 0x8b, 0x50, 0xa8, 0x77, 0xb7, 0xd5, 0xf7, 0xce, 0x40, 0xdb, + 0xae, 0x59, 0x29, 0x79, 0x1b, 0xc6, 0x85, 0xd3, 0x99, 0x72, 0x3b, 0xc5, 0x4e, 0x92, 0x1e, 0x6a, + 0x49, 0x97, 0x18, 0x05, 0x9d, 0xbc, 0x07, 0x13, 0x35, 0xa7, 0x43, 0x5b, 0x8e, 0x4b, 0x15, 0x07, + 0x0f, 0x1c, 0xcb, 0x8e, 0x80, 0xa7, 0xde, 0x40, 0x55, 0x02, 0xdd, 0x3d, 0x6e, 0x68, 0x70, 0xf7, + 0xb8, 0xf7, 0x60, 0x62, 0x85, 0xee, 0x38, 0xae, 0x23, 0xfa, 0x67, 0x38, 0xae, 0xb8, 0x19, 0xc1, + 0x75, 0x6a, 0x8d, 0x80, 0x2c, 0xc1, 0xa4, 0x49, 0x3b, 0x5e, 0xe0, 0x84, 0x9e, 0x7f, 0xb0, 0x65, + 0x56, 0x85, 0x5d, 0x11, 0x2a, 0x46, 0xfd, 0xa8, 0xc0, 0xea, 0xfa, 0xea, 0x49, 0xa4, 0x93, 0x90, + 0x7b, 0x30, 0x13, 0x03, 0x74, 0x7b, 0x3c, 0xf1, 0xe0, 0x15, 0xf1, 0x49, 0x5b, 0xd2, 0xa7, 0x49, + 0xf5, 0x6f, 0x32, 0xe9, 0x8e, 0xb0, 0xcb, 0x4f, 0x7e, 0x93, 0x4f, 0x77, 0xb2, 0xbf, 0xc9, 0xa4, + 0x3b, 0xc6, 0xaf, 0x17, 0xe0, 0x4c, 0x8f, 0xad, 0x8d, 0xdc, 0xd3, 0xa7, 0xeb, 0x8b, 0xfd, 0x77, + 0xc2, 0xe3, 0xa7, 0xe9, 0x3a, 0x94, 0x56, 0xef, 0xe2, 0x85, 0x9e, 0x9b, 0x13, 0x2c, 0x57, 0xa4, + 0x10, 0x8a, 0xcd, 0xa7, 0xfb, 0xe8, 0x93, 0x23, 0xcd, 0x10, 0x1a, 0x5a, 0x68, 0xa0, 0x14, 0xe5, + 0xc2, 0x5f, 0xcc, 0x8b, 0x79, 0x9b, 0x88, 0xe3, 0x9a, 0x3b, 0x51, 0x1c, 0xd7, 0x2f, 0xc0, 0xc4, + 0xea, 0x5d, 0xae, 0xc5, 0x5c, 0x93, 0x8a, 0x33, 0xd1, 0x85, 0x74, 0x5f, 0x3e, 0x9f, 0x25, 0x54, + 0x68, 0x1a, 0x05, 0xd9, 0x82, 0x59, 0xfe, 0x6d, 0xce, 0x8e, 0xd3, 0xe0, 0xe1, 0x20, 0x1d, 0xbb, + 0x25, 0x66, 0xd8, 0x8b, 0x47, 0x87, 0xe5, 0x32, 0xdd, 0x47, 0x6f, 0x23, 0x51, 0x6e, 0x05, 0x88, + 0xa0, 0xba, 0x1d, 0x65, 0xd0, 0xab, 0xc1, 0xe5, 0xcc, 0x31, 0xac, 0x90, 0xd5, 0xc6, 0xea, 0x66, + 0xb8, 0x1c, 0xc9, 0xf8, 0xa3, 0x61, 0x58, 0xe8, 0x2d, 0x76, 0x91, 0xf7, 0xf5, 0x01, 0xbc, 0x78, + 0xac, 0xa0, 0x76, 0xfc, 0x18, 0x7e, 0x00, 0x73, 0xab, 0x6e, 0x48, 0xfd, 0x8e, 0xef, 0xc8, 0xa0, + 0x74, 0x6b, 0x5e, 0x20, 0xbd, 0xbb, 0xf0, 0x71, 0x83, 0x46, 0xe5, 0xc2, 0x4f, 0x11, 0xdf, 0xe3, + 0xd4, 0xc7, 0x8d, 0x2c, 0x0e, 0x64, 0x15, 0xa6, 0x14, 0x78, 0xab, 0xbb, 0xab, 0xda, 0x48, 0xa8, + 0x3c, 0x5b, 0x5d, 0xd5, 0xf5, 0x25, 0x41, 0x84, 0x1e, 0x64, 0xa1, 0x1d, 0x3a, 0x8d, 0x3b, 0x0f, + 0xef, 0xd6, 0xc5, 0x70, 0x72, 0x0f, 0x32, 0x84, 0x5a, 0x1f, 0x3e, 0xde, 0xd7, 0xe4, 0xa6, 0x18, + 0x79, 0xe1, 0x17, 0x4f, 0xb4, 0x13, 0x7e, 0x1e, 0x20, 0x5e, 0x4a, 0x6a, 0x80, 0x89, 0x78, 0xe9, + 0xe9, 0x4e, 0xa2, 0x12, 0x4a, 0xd6, 0x60, 0x3a, 0xfe, 0x75, 0xff, 0xb1, 0x2b, 0xdf, 0x29, 0xb9, + 0xb6, 0x57, 0x59, 0xb9, 0x1e, 0x2b, 0x53, 0x45, 0xf1, 0x04, 0x19, 0x59, 0x84, 0xe2, 0x43, 0xcf, + 0xdf, 0xdf, 0x61, 0x63, 0x3c, 0x14, 0x5f, 0x16, 0x1e, 0x0b, 0x98, 0x2a, 0x14, 0x4b, 0x3c, 0xb6, + 0x5c, 0x56, 0xdd, 0x47, 0x8e, 0xef, 0xa1, 0x5d, 0x89, 0x6a, 0x59, 0x49, 0x63, 0xb0, 0x16, 0xda, + 0x27, 0x06, 0x93, 0xcb, 0x30, 0x5c, 0x69, 0x84, 0x9e, 0x2f, 0xb6, 0x3f, 0x3e, 0x53, 0x18, 0x40, + 0x9b, 0x29, 0x0c, 0xc0, 0x3a, 0x91, 0xed, 0x49, 0xa3, 0x71, 0x27, 0xea, 0x1b, 0x11, 0x2b, 0x65, + 0x97, 0x1d, 0x93, 0xee, 0xa0, 0x76, 0x54, 0x8b, 0x52, 0xbc, 0x93, 0x7a, 0xc9, 0x10, 0x68, 0xc6, + 0x5f, 0x82, 0x9e, 0x53, 0x9e, 0x49, 0x97, 0x27, 0x9b, 0xf2, 0xeb, 0xf6, 0x00, 0x53, 0xfe, 0xb5, + 0xc8, 0xf5, 0x54, 0x0d, 0xd6, 0x85, 0x10, 0x55, 0xae, 0x11, 0x4e, 0xa8, 0xfa, 0xfc, 0x2b, 0x9c, + 0x64, 0xfe, 0xfd, 0xad, 0xe2, 0x49, 0xe6, 0x9f, 0xe8, 0xdf, 0xfc, 0xa0, 0xfd, 0x5b, 0x18, 0xa8, + 0x7f, 0xd9, 0xa1, 0x12, 0x85, 0xc8, 0xae, 0xd9, 0xa1, 0xb6, 0x23, 0x46, 0x71, 0xcd, 0xad, 0x8e, + 0xad, 0x85, 0x91, 0xd4, 0x49, 0x14, 0x21, 0x01, 0x39, 0x0c, 0xa7, 0x85, 0x84, 0x04, 0xbd, 0x8a, + 0xce, 0x36, 0x02, 0x79, 0xe6, 0xd7, 0xd1, 0x91, 0x51, 0x4c, 0x36, 0x6e, 0x75, 0x24, 0xc5, 0x04, + 0xee, 0xe3, 0xa8, 0x3d, 0xfb, 0x68, 0x44, 0xc9, 0x79, 0x3e, 0x7a, 0xa2, 0x79, 0xce, 0x0d, 0xed, + 0xfd, 0x75, 0x6f, 0xd7, 0x91, 0xee, 0x6e, 0xd2, 0xd0, 0xde, 0xb7, 0x5a, 0x0c, 0x9a, 0x30, 0xb4, + 0xe7, 0xa8, 0xe4, 0x0a, 0x8c, 0xb0, 0x1f, 0xd5, 0x15, 0x61, 0x0a, 0x83, 0x4a, 0x0f, 0x24, 0xd2, + 0x7d, 0x0c, 0x39, 0x92, 0xac, 0x66, 0xb5, 0x6d, 0x3b, 0x2d, 0x11, 0xce, 0x29, 0xae, 0x86, 0x32, + 0x68, 0xb2, 0x1a, 0x44, 0x25, 0x0d, 0x98, 0x30, 0xe9, 0x4e, 0xcd, 0xf7, 0x42, 0xda, 0x08, 0x69, + 0x53, 0x5c, 0xf4, 0xa4, 0xae, 0x63, 0xc9, 0xf3, 0xf8, 0x25, 0x16, 0xdd, 0xd1, 0x72, 0xdf, 0x3d, + 0x2c, 0x03, 0x03, 0x71, 0x07, 0x56, 0x26, 0xf2, 0xb0, 0xf1, 0xef, 0x48, 0x62, 0xf5, 0x60, 0x53, + 0x99, 0x92, 0x6f, 0xb0, 0xad, 0x3e, 0xea, 0x92, 0xb8, 0xb2, 0x89, 0x1e, 0x95, 0xbd, 0x9e, 0x59, + 0x59, 0x59, 0xe9, 0xed, 0xcc, 0x4a, 0x33, 0x2b, 0x21, 0xef, 0xc0, 0xf8, 0x72, 0x75, 0xd9, 0x73, + 0x77, 0x9c, 0xdd, 0xfa, 0x5a, 0x05, 0x6f, 0x8b, 0x42, 0x5e, 0x6b, 0x38, 0x56, 0x03, 0xe1, 0x56, + 0xb0, 0x67, 0x6b, 0x11, 0x46, 0x62, 0x7c, 0x72, 0x1b, 0xa6, 0xe4, 0x4f, 0x93, 0xee, 0x30, 0x79, + 0x6d, 0x4a, 0x71, 0x78, 0x8f, 0x38, 0xb0, 0x8e, 0xd0, 0x45, 0xb6, 0x04, 0x19, 0x9b, 0x8c, 0x2b, + 0xb4, 0xd3, 0xf2, 0x0e, 0xd8, 0xe7, 0x6d, 0x3a, 0xd4, 0xc7, 0x6b, 0xa1, 0x98, 0x8c, 0xcd, 0xa8, + 0xc4, 0x0a, 0x1d, 0xdd, 0x00, 0x48, 0x27, 0x62, 0xa2, 0x9f, 0x98, 0xe2, 0x0f, 0x9c, 0xc0, 0xd9, + 0x76, 0x5a, 0x4e, 0x78, 0x80, 0x17, 0x42, 0x21, 0xfb, 0xc8, 0x75, 0xf1, 0x28, 0x2a, 0x55, 0x45, + 0xbf, 0x14, 0xa9, 0xf1, 0xab, 0x79, 0x78, 0xae, 0x9f, 0x72, 0x84, 0xd4, 0xf5, 0x7d, 0xf0, 0xd2, + 0x00, 0x0a, 0x95, 0xe3, 0x77, 0xc2, 0xd5, 0x1e, 0xf7, 0x0c, 0xec, 0x8c, 0xc4, 0x3d, 0x43, 0xed, + 0x8c, 0xc4, 0x8d, 0xe3, 0x91, 0xd8, 0xe6, 0x3e, 0x6a, 0xac, 0x8b, 0x9b, 0x30, 0xb6, 0xec, 0xb9, + 0x21, 0x7d, 0x12, 0x26, 0x22, 0x3b, 0x71, 0x60, 0x32, 0xce, 0x87, 0x44, 0x35, 0xfe, 0x65, 0x01, + 0xce, 0xf7, 0xd5, 0x0e, 0x90, 0x4d, 0xbd, 0xd7, 0x2e, 0x0f, 0xa2, 0x52, 0x38, 0xbe, 0xdb, 0x16, + 0x53, 0x86, 0xe3, 0xc7, 0x3b, 0x2b, 0x9b, 0x40, 0x78, 0x00, 0x9b, 0xdb, 0x2d, 0x6f, 0x1b, 0xf5, + 0x47, 0x8e, 0xbb, 0x2b, 0x02, 0xdf, 0x70, 0xc7, 0x5b, 0x2c, 0xb5, 0x76, 0x5b, 0xde, 0x36, 0xd7, + 0x43, 0x39, 0xae, 0x2a, 0x16, 0x65, 0x50, 0x2f, 0xfc, 0xcb, 0x9c, 0xe8, 0xf8, 0xcf, 0xc0, 0x28, + 0x7e, 0x7e, 0xd4, 0xed, 0x5c, 0xb3, 0x8f, 0x3b, 0xbb, 0xa3, 0x6b, 0xf6, 0x39, 0x1a, 0xb9, 0x01, + 0xc5, 0x65, 0xbb, 0xd5, 0x52, 0x62, 0x69, 0xa1, 0xd2, 0xa0, 0x81, 0xb0, 0x84, 0x47, 0x85, 0x44, + 0x64, 0x47, 0x21, 0xff, 0x5b, 0x39, 0x7f, 0x70, 0x03, 0x16, 0x64, 0x89, 0x23, 0x48, 0x41, 0xc6, + 0xc4, 0x01, 0x0d, 0x2f, 0x8a, 0xd6, 0xc3, 0x13, 0x07, 0x30, 0x80, 0x96, 0x38, 0x80, 0x01, 0x8c, + 0x5f, 0x1a, 0x86, 0xe7, 0xfb, 0xab, 0xcd, 0xc8, 0x96, 0x3e, 0xac, 0xaf, 0x0e, 0xa4, 0x6c, 0x3b, + 0x7e, 0x5c, 0x65, 0x1a, 0x0e, 0xde, 0x21, 0x97, 0xd2, 0x5e, 0xac, 0xdf, 0x3b, 0x2c, 0x2b, 0x6e, + 0x3a, 0x77, 0x3c, 0xc7, 0x55, 0xde, 0x79, 0xbf, 0x9e, 0x12, 0x14, 0xc6, 0x17, 0x6f, 0x0e, 0xf6, + 0x65, 0x31, 0x1d, 0xdf, 0xab, 0x06, 0x14, 0x30, 0xc8, 0x07, 0x30, 0x74, 0xbf, 0xba, 0xb2, 0x2c, + 0x1e, 0x5d, 0x3e, 0x33, 0x58, 0x65, 0x8c, 0x42, 0x54, 0x83, 0xf6, 0x04, 0x9e, 0xd3, 0x6c, 0xa8, + 0xf6, 0x04, 0xac, 0x7c, 0xe1, 0x4d, 0x28, 0x25, 0x3f, 0x8a, 0x5c, 0x84, 0x21, 0x6c, 0x9a, 0xe2, + 0xe4, 0x9b, 0xf8, 0x36, 0x2c, 0x5f, 0xf8, 0x99, 0x1c, 0x40, 0x5c, 0x09, 0x13, 0xb7, 0xaa, 0x41, + 0xd0, 0x8d, 0x02, 0x9a, 0xa2, 0xb8, 0xe5, 0x20, 0x44, 0x3d, 0x41, 0x39, 0x0e, 0xf9, 0x00, 0x9d, + 0x8c, 0xd1, 0xac, 0x16, 0x07, 0x65, 0x6d, 0x73, 0xb3, 0x26, 0xc8, 0xb9, 0xe9, 0x12, 0xca, 0xd4, + 0x91, 0x3d, 0x2e, 0xb7, 0x4c, 0xdf, 0x0b, 0xc3, 0x8e, 0xc5, 0x59, 0x9a, 0xbd, 0xc8, 0x17, 0x36, + 0xc4, 0x62, 0xc1, 0x78, 0x6a, 0x6a, 0x70, 0x0c, 0xf1, 0x5d, 0x22, 0x9e, 0x9a, 0x16, 0x59, 0x43, + 0x8f, 0xa7, 0xa6, 0x12, 0x19, 0xff, 0x3e, 0x07, 0x67, 0x7b, 0x2a, 0x7a, 0x48, 0x4d, 0x9f, 0xa1, + 0x2f, 0x1f, 0xa7, 0x19, 0x3a, 0x76, 0x72, 0x2e, 0x7c, 0x4b, 0x2e, 0xf6, 0x77, 0x61, 0xa2, 0xde, + 0xdd, 0x4e, 0xde, 0x8f, 0x79, 0xb4, 0x43, 0x05, 0xae, 0x8a, 0x01, 0x2a, 0x3e, 0x6b, 0xbf, 0x8c, + 0x28, 0x21, 0xcc, 0x80, 0x15, 0xdf, 0x83, 0x28, 0x22, 0x4e, 0x3a, 0x9e, 0x9c, 0x4e, 0x64, 0xfc, + 0xdd, 0x7c, 0xb6, 0xa2, 0xe1, 0xf6, 0x72, 0xed, 0x24, 0x8a, 0x86, 0xdb, 0xcb, 0xb5, 0xe3, 0xdb, + 0xfe, 0xdf, 0xc9, 0xb6, 0x73, 0x8b, 0x38, 0x7e, 0x6c, 0xc8, 0x07, 0x24, 0x69, 0x11, 0x27, 0x8e, + 0x98, 0x20, 0x61, 0x11, 0x27, 0x90, 0xc9, 0xeb, 0x30, 0xb6, 0xee, 0xf1, 0x50, 0x6f, 0xb2, 0xc5, + 0x3c, 0x64, 0x8c, 0x04, 0xaa, 0x67, 0x4c, 0x84, 0xc9, 0xee, 0x76, 0xfa, 0xc0, 0x4b, 0x17, 0x0b, + 0x9c, 0x87, 0x89, 0xe9, 0xa2, 0x3f, 0xb3, 0xe8, 0x64, 0xc6, 0xdf, 0x1b, 0x06, 0xe3, 0x78, 0x25, + 0x31, 0xf9, 0xa2, 0xde, 0x77, 0x57, 0x07, 0x56, 0x2f, 0x0f, 0x74, 0x6e, 0x55, 0xba, 0x4d, 0x87, + 0xba, 0x0d, 0x3d, 0x4e, 0x9b, 0x80, 0xa9, 0x7b, 0xbe, 0xc4, 0xfb, 0x28, 0x81, 0x39, 0x16, 0xfe, + 0x69, 0x21, 0x5e, 0x6a, 0x09, 0xf9, 0x22, 0xf7, 0x11, 0xe4, 0x0b, 0x72, 0x17, 0x4a, 0x2a, 0x44, + 0x51, 0x54, 0xa2, 0xf8, 0xa7, 0x31, 0x4a, 0x7c, 0x54, 0x8a, 0x50, 0x17, 0x52, 0x0a, 0x83, 0x0b, + 0x29, 0x09, 0x45, 0xe9, 0xd0, 0xc9, 0x14, 0xa5, 0x22, 0xae, 0x5b, 0x20, 0x4e, 0xe9, 0x61, 0x3d, + 0xae, 0x5b, 0xc6, 0x49, 0xad, 0xa2, 0xcb, 0xd0, 0x74, 0xf8, 0x53, 0x09, 0x5d, 0x14, 0x85, 0xa6, + 0xe3, 0xf4, 0x59, 0xa1, 0xe9, 0x22, 0x12, 0x76, 0xe2, 0x9b, 0x5d, 0x97, 0xa7, 0xe4, 0x19, 0x8d, + 0x4f, 0x7c, 0xbf, 0xeb, 0x5a, 0xc9, 0xb4, 0x3c, 0x11, 0xa2, 0xf1, 0x0f, 0x87, 0xb2, 0x25, 0xac, + 0xf8, 0x1d, 0xe1, 0x04, 0x12, 0x56, 0x44, 0xf4, 0xc9, 0xcc, 0xd4, 0x2d, 0x98, 0x95, 0x56, 0xfa, + 0x58, 0x7b, 0x93, 0xfa, 0x5b, 0xe6, 0xba, 0x18, 0x62, 0xd4, 0xdb, 0x45, 0xf6, 0xfd, 0x1d, 0x51, + 0x6e, 0x75, 0x7d, 0x4d, 0x6f, 0x97, 0x41, 0xbf, 0xf0, 0x0f, 0xa4, 0x5a, 0x52, 0x1d, 0x04, 0x8c, + 0xa8, 0x90, 0xcb, 0x1a, 0x84, 0x6e, 0x57, 0x1b, 0x46, 0x9d, 0x84, 0xef, 0xbd, 0x91, 0x0a, 0x79, + 0x4b, 0x17, 0xb8, 0x55, 0xb5, 0xb3, 0xce, 0x25, 0x41, 0x44, 0x76, 0xe1, 0x6c, 0x7c, 0x1f, 0x51, + 0xae, 0x5b, 0xc8, 0x91, 0x37, 0xf8, 0xf2, 0xd1, 0x61, 0xf9, 0x65, 0xe5, 0x3e, 0xa3, 0xde, 0xda, + 0x12, 0xdc, 0x7b, 0xf3, 0x62, 0xfb, 0xed, 0x92, 0x6f, 0xbb, 0x8d, 0x3d, 0x65, 0xce, 0xe3, 0x7e, + 0xbb, 0x8d, 0xd0, 0x54, 0xf8, 0xa6, 0x18, 0xd9, 0xf8, 0x9b, 0xf9, 0x6c, 0xbd, 0x8e, 0x78, 0x2e, + 0x3a, 0x81, 0x5e, 0x87, 0x53, 0x1c, 0x7f, 0x4a, 0xfc, 0x3d, 0x79, 0x4a, 0xbc, 0x0c, 0xa3, 0x9b, + 0xd4, 0xb5, 0xdd, 0x28, 0x2c, 0x1a, 0x9a, 0xad, 0x84, 0x1c, 0x64, 0xca, 0x32, 0xf2, 0x3e, 0x90, + 0x9a, 0xed, 0x53, 0x37, 0x5c, 0xf6, 0xda, 0x1d, 0xdb, 0x0f, 0xdb, 0x98, 0xb4, 0x88, 0x1f, 0x0d, + 0x2f, 0x1c, 0x1d, 0x96, 0xcf, 0x77, 0xb0, 0xd4, 0x6a, 0x28, 0xc5, 0xaa, 0x44, 0x9e, 0x26, 0x26, + 0xd7, 0x60, 0x54, 0x5a, 0x63, 0x14, 0xe2, 0x40, 0xb0, 0x69, 0x4b, 0x0c, 0x89, 0x65, 0xfc, 0xd3, + 0x61, 0xb8, 0x70, 0xdc, 0xdb, 0x18, 0xd9, 0x01, 0xb8, 0xef, 0x6e, 0x7b, 0xb6, 0xdf, 0x64, 0x77, + 0x86, 0xdc, 0xb1, 0x92, 0xa5, 0x4a, 0x7c, 0x35, 0xa6, 0x64, 0x85, 0xdc, 0x00, 0xd4, 0x8b, 0x60, + 0xa6, 0xc2, 0x99, 0x7c, 0x15, 0x8a, 0x26, 0x6d, 0x78, 0x8f, 0xa8, 0xd0, 0x7f, 0x8e, 0x2f, 0x7e, + 0x76, 0xd0, 0x5a, 0x24, 0x1d, 0xd6, 0x81, 0x6e, 0xb4, 0xbe, 0x80, 0x98, 0x11, 0x4f, 0xf2, 0x35, + 0x18, 0xe7, 0xb9, 0xa9, 0x2a, 0x3b, 0xa1, 0xd0, 0x91, 0x1e, 0x1f, 0x06, 0x27, 0xc7, 0x36, 0x49, + 0x9e, 0xed, 0xca, 0xb2, 0x77, 0x34, 0xb7, 0x1c, 0x1e, 0x06, 0x47, 0x61, 0xb9, 0xf0, 0x5f, 0xe4, + 0x61, 0x4a, 0x6f, 0x30, 0x59, 0x87, 0x52, 0xd5, 0x75, 0x42, 0xc7, 0x6e, 0xe9, 0x66, 0xd0, 0xe2, + 0xa2, 0xee, 0xf0, 0x32, 0x2b, 0xd3, 0x4a, 0x38, 0x45, 0xc9, 0xe6, 0x0c, 0x1b, 0xba, 0x20, 0xe4, + 0x66, 0x22, 0x3c, 0x28, 0xb3, 0x58, 0xc4, 0x2f, 0xf0, 0x18, 0xe0, 0x71, 0xa9, 0xc5, 0xc3, 0xa0, + 0xeb, 0x01, 0x67, 0x93, 0xc4, 0xe4, 0x11, 0x90, 0x8d, 0x6e, 0x10, 0xf2, 0x12, 0xea, 0x2f, 0xd1, + 0x1d, 0xcf, 0x1f, 0x24, 0xfe, 0xcd, 0xab, 0xa2, 0x73, 0x9e, 0x6f, 0x77, 0x83, 0xd0, 0xf2, 0x05, + 0xb9, 0xb5, 0x8d, 0xf4, 0x89, 0x4e, 0xca, 0xa8, 0x61, 0x61, 0x03, 0x26, 0xd4, 0x51, 0x43, 0xb3, + 0x39, 0xa7, 0xed, 0x48, 0xc7, 0x11, 0x6e, 0x36, 0xc7, 0x00, 0x26, 0x87, 0x93, 0xe7, 0x44, 0xc0, + 0xb8, 0x7c, 0x6c, 0x5d, 0x16, 0x07, 0x86, 0x33, 0x7e, 0x38, 0x07, 0xa7, 0xb3, 0x4d, 0xae, 0xc8, + 0x87, 0x89, 0xa7, 0xe1, 0x5c, 0xbf, 0x87, 0x73, 0x69, 0xa7, 0xf5, 0xd1, 0x1e, 0x87, 0x8d, 0xbf, + 0x3c, 0x94, 0x92, 0xb2, 0x32, 0x38, 0x92, 0xdb, 0x99, 0xe3, 0x98, 0x53, 0xce, 0xc5, 0xf4, 0x38, + 0x66, 0x8e, 0xde, 0xdb, 0x30, 0x85, 0x8c, 0xe3, 0xc9, 0xa5, 0x28, 0x95, 0xf9, 0x27, 0x2b, 0xe6, + 0xd6, 0x09, 0x5c, 0x52, 0x05, 0x82, 0x90, 0x25, 0x2f, 0x54, 0x02, 0x35, 0x28, 0x37, 0x6b, 0xce, + 0x61, 0xdb, 0x0b, 0x2d, 0x35, 0x64, 0x43, 0x06, 0x11, 0xf9, 0x3c, 0x4c, 0xca, 0xe1, 0x5c, 0xc6, + 0x5b, 0x8d, 0x62, 0x32, 0x2e, 0xd7, 0xa2, 0x85, 0xa2, 0xa8, 0xa9, 0x23, 0x92, 0x36, 0x0f, 0xdd, + 0x25, 0x80, 0xb4, 0x59, 0x09, 0x07, 0x88, 0x8f, 0xf6, 0x8a, 0x98, 0x7d, 0xe7, 0x78, 0x36, 0x3a, + 0x49, 0x6b, 0xd9, 0x61, 0x62, 0xea, 0x25, 0x79, 0x93, 0x5d, 0x98, 0x54, 0xb2, 0xd4, 0x55, 0xc2, + 0x01, 0x92, 0x24, 0xbe, 0x2c, 0x2a, 0x3b, 0xab, 0xa6, 0xbe, 0x4b, 0x57, 0xa5, 0xf3, 0x35, 0xbe, + 0x95, 0x87, 0x29, 0x7e, 0x89, 0xe5, 0x76, 0x77, 0xcf, 0xac, 0x81, 0xe4, 0x5b, 0x9a, 0x81, 0xa4, + 0xcc, 0x44, 0xa0, 0x36, 0x6d, 0x20, 0x73, 0xf6, 0x3d, 0x20, 0x69, 0x1a, 0x62, 0xc2, 0x84, 0x0a, + 0xed, 0x6f, 0xcc, 0x78, 0x3d, 0x4e, 0x5a, 0x21, 0xb4, 0x13, 0x68, 0x9e, 0x1a, 0x98, 0x1a, 0x0f, + 0xe3, 0xc7, 0xf2, 0x30, 0xa9, 0x98, 0xb3, 0x3f, 0xb3, 0x1d, 0xff, 0xa6, 0xd6, 0xf1, 0xf3, 0x51, + 0xa4, 0x9a, 0xa8, 0x65, 0x03, 0xf5, 0x7b, 0x17, 0x66, 0x52, 0x24, 0x49, 0xaf, 0x80, 0xdc, 0x20, + 0x5e, 0x01, 0xaf, 0xa5, 0x23, 0xe0, 0xf3, 0xfc, 0x97, 0x51, 0x3c, 0x64, 0x35, 0xe4, 0xfe, 0x4f, + 0xe4, 0x61, 0x4e, 0xfc, 0xc2, 0x94, 0x31, 0x5c, 0x1d, 0xf3, 0xcc, 0x8e, 0x45, 0x45, 0x1b, 0x8b, + 0xb2, 0x3e, 0x16, 0x4a, 0x03, 0x7b, 0x0f, 0x89, 0xf1, 0xc3, 0x00, 0xf3, 0xbd, 0x08, 0x06, 0x0e, + 0x61, 0x17, 0x87, 0xc8, 0xc9, 0x0f, 0x10, 0x22, 0x67, 0x1d, 0x4a, 0x58, 0x95, 0xf0, 0xa3, 0x0b, + 0xb6, 0xcc, 0xaa, 0xe8, 0x24, 0x94, 0x3e, 0x78, 0x5e, 0x1f, 0xe1, 0x7c, 0x17, 0x24, 0x9e, 0x2e, + 0x52, 0x94, 0xe4, 0x17, 0x73, 0x30, 0x85, 0xc0, 0xd5, 0x47, 0x4c, 0xdc, 0x64, 0xcc, 0x86, 0x44, + 0xec, 0x94, 0xc8, 0xe4, 0xb1, 0x1e, 0xfa, 0x8e, 0xbb, 0x2b, 0x6c, 0x1e, 0xb7, 0x85, 0xcd, 0xe3, + 0xdb, 0xdc, 0x56, 0xf3, 0x6a, 0xc3, 0x6b, 0x5f, 0xdb, 0xf5, 0xed, 0x47, 0x0e, 0xf7, 0xd4, 0xb0, + 0x5b, 0xd7, 0xe2, 0xb4, 0xcd, 0x1d, 0x27, 0x91, 0x50, 0x59, 0xb0, 0x42, 0x7b, 0x52, 0xfe, 0xa1, + 0x14, 0xab, 0x4d, 0xbe, 0xb0, 0xe8, 0x5f, 0x44, 0x7e, 0x00, 0xce, 0x70, 0x5d, 0xf5, 0xb2, 0xe7, + 0x86, 0x8e, 0xdb, 0xf5, 0xba, 0xc1, 0x92, 0xdd, 0xd8, 0xef, 0x76, 0x02, 0x11, 0xe1, 0x0a, 0x5b, + 0xde, 0x88, 0x0a, 0xad, 0x6d, 0x5e, 0xaa, 0x45, 0x99, 0xcc, 0x66, 0x40, 0xd6, 0x60, 0x86, 0x17, + 0x55, 0xba, 0xa1, 0x57, 0x6f, 0xd8, 0x2d, 0x26, 0x10, 0x8f, 0x22, 0x57, 0x6e, 0xd8, 0xd5, 0x0d, + 0x3d, 0x2b, 0xe0, 0x70, 0xf5, 0xc1, 0x25, 0x45, 0x44, 0xaa, 0x30, 0x6d, 0x52, 0xbb, 0xb9, 0x61, + 0x3f, 0x59, 0xb6, 0x3b, 0x76, 0xc3, 0x09, 0x79, 0xee, 0x98, 0x02, 0x57, 0x29, 0xf8, 0xd4, 0x6e, + 0x5a, 0x6d, 0xfb, 0x89, 0xd5, 0x10, 0x85, 0xfa, 0xa3, 0xbd, 0x46, 0x17, 0xb1, 0x72, 0xdc, 0x88, + 0xd5, 0x58, 0x92, 0x95, 0xe3, 0xf6, 0x66, 0x15, 0xd3, 0x49, 0x56, 0x3c, 0x89, 0x1f, 0xf7, 0xf9, + 0x85, 0x0b, 0xb9, 0x4b, 0x39, 0x85, 0x95, 0xc8, 0xfc, 0x87, 0xfe, 0xbf, 0x49, 0x56, 0x0a, 0x1d, + 0x9b, 0x79, 0x0f, 0x7d, 0x27, 0xa4, 0x6a, 0x0b, 0xc7, 0xf1, 0xb3, 0xb0, 0xff, 0xd1, 0x5b, 0xba, + 0x57, 0x13, 0x53, 0x94, 0x31, 0x37, 0xa5, 0x91, 0x13, 0x29, 0x6e, 0xd9, 0xad, 0x4c, 0x51, 0x46, + 0xdc, 0xd4, 0x76, 0x4e, 0x62, 0x3b, 0x15, 0x6e, 0x3d, 0x1a, 0x9a, 0xa2, 0x24, 0xf7, 0x58, 0xa7, + 0x85, 0xec, 0xe6, 0xee, 0xb9, 0xc2, 0x19, 0x79, 0x0a, 0x3f, 0xed, 0x25, 0x21, 0x36, 0x94, 0x7c, + 0x59, 0x6c, 0x65, 0xb8, 0x26, 0x27, 0x89, 0xc9, 0x9f, 0x83, 0xe9, 0xad, 0x80, 0xde, 0xaa, 0xd6, + 0xea, 0x32, 0xf6, 0x38, 0xbe, 0x11, 0x4e, 0x2d, 0x5e, 0x3f, 0x66, 0xd3, 0xb9, 0xaa, 0xd2, 0x60, + 0x16, 0x64, 0x3e, 0x6e, 0xdd, 0x80, 0x5a, 0x3b, 0x4e, 0x27, 0x88, 0xd2, 0x64, 0xa8, 0xe3, 0x96, + 0xa8, 0xca, 0x58, 0x83, 0x99, 0x14, 0x1b, 0x32, 0x05, 0xc0, 0x80, 0xd6, 0xd6, 0xbd, 0xfa, 0xea, + 0x66, 0xe9, 0x53, 0xa4, 0x04, 0x13, 0xf8, 0x7b, 0xf5, 0x5e, 0x65, 0x69, 0x7d, 0x75, 0xa5, 0x94, + 0x23, 0x33, 0x30, 0x89, 0x90, 0x95, 0x6a, 0x9d, 0x83, 0xf2, 0x3c, 0x79, 0xa5, 0x59, 0xe2, 0x4b, + 0x37, 0xc4, 0xd7, 0x25, 0x76, 0xa6, 0x18, 0x7f, 0x2d, 0x0f, 0x67, 0xe5, 0xb1, 0x42, 0xc3, 0xc7, + 0x9e, 0xbf, 0xef, 0xb8, 0xbb, 0xcf, 0xf8, 0xe9, 0x70, 0x4b, 0x3b, 0x1d, 0x5e, 0x4a, 0x9c, 0xd4, + 0x89, 0x56, 0xf6, 0x39, 0x22, 0xbe, 0x33, 0x06, 0xe7, 0xfb, 0x52, 0x91, 0xf7, 0xd9, 0x69, 0xee, + 0x50, 0x37, 0xac, 0x36, 0x5b, 0x94, 0x89, 0xa8, 0x5e, 0x37, 0x14, 0xce, 0xef, 0x2f, 0xe2, 0x13, + 0x1a, 0x16, 0x5a, 0x4e, 0xb3, 0x45, 0xad, 0x90, 0x17, 0x6b, 0xd3, 0x2d, 0x4d, 0xcd, 0x58, 0x46, + 0x19, 0xd9, 0xab, 0x6e, 0x48, 0xfd, 0x47, 0xe8, 0xbc, 0x14, 0xb1, 0xdc, 0xa7, 0xb4, 0x63, 0xd9, + 0xac, 0xd4, 0x72, 0x44, 0xb1, 0xce, 0x32, 0x45, 0x4d, 0x6e, 0x29, 0x2c, 0x51, 0xca, 0xdf, 0xb0, + 0x9f, 0x08, 0x07, 0x08, 0x91, 0x29, 0x28, 0x62, 0xc9, 0xc3, 0xca, 0xb4, 0xed, 0x27, 0x66, 0x9a, + 0x84, 0x7c, 0x05, 0x4e, 0x89, 0x03, 0x48, 0x84, 0x3d, 0x95, 0x2d, 0xe6, 0x41, 0x55, 0x5f, 0x61, + 0x17, 0x33, 0xe9, 0x3b, 0x2e, 0x43, 0x19, 0x67, 0xb5, 0x3a, 0x9b, 0x0b, 0xd9, 0x64, 0x07, 0x72, + 0xa2, 0x3b, 0x36, 0x68, 0x10, 0xc8, 0xd8, 0x41, 0x42, 0x37, 0xab, 0x76, 0xa6, 0xd5, 0xe6, 0xe5, + 0x66, 0x4f, 0x4a, 0xb2, 0x06, 0x53, 0x0f, 0xe9, 0xb6, 0x3a, 0x3e, 0x23, 0xd1, 0x56, 0x55, 0x7a, + 0x4c, 0xb7, 0x7b, 0x0f, 0x4e, 0x82, 0x8e, 0x38, 0xf8, 0xcc, 0xff, 0xe4, 0x60, 0x9d, 0x5d, 0x9c, + 0x5d, 0xea, 0xe3, 0xfd, 0x77, 0x14, 0x37, 0x83, 0xf9, 0x58, 0x42, 0xd6, 0xcb, 0x85, 0xee, 0x08, + 0xc3, 0x75, 0xb4, 0x04, 0xdc, 0x4a, 0xe4, 0x33, 0x4f, 0x73, 0x25, 0x5f, 0x83, 0x69, 0xd3, 0xeb, + 0x86, 0x8e, 0xbb, 0x5b, 0x67, 0x37, 0x4c, 0xba, 0xcb, 0x0f, 0xa4, 0x38, 0x32, 0x7b, 0xa2, 0x54, + 0x18, 0x97, 0x71, 0xa0, 0x15, 0x08, 0xa8, 0x76, 0x22, 0xe8, 0x04, 0xe4, 0xab, 0x30, 0xc5, 0xc3, + 0x47, 0x46, 0x15, 0x8c, 0x69, 0x49, 0x4d, 0xf5, 0xc2, 0x07, 0xd7, 0x85, 0xbd, 0x3a, 0x42, 0xb3, + 0x2a, 0x48, 0x70, 0x23, 0x5f, 0x12, 0x9d, 0x55, 0x73, 0xdc, 0xdd, 0x68, 0x1a, 0x03, 0xf6, 0xfc, + 0x95, 0xb8, 0x4b, 0x3a, 0xec, 0x73, 0xe5, 0x34, 0xee, 0xe1, 0x7c, 0x93, 0xe6, 0x43, 0x42, 0x38, + 0x5f, 0x09, 0x02, 0x27, 0x08, 0x45, 0x88, 0x88, 0xd5, 0x27, 0xb4, 0xd1, 0x65, 0xc8, 0x0f, 0x3d, + 0x7f, 0x9f, 0xfa, 0xdc, 0xfd, 0x73, 0x78, 0xe9, 0xea, 0xd1, 0x61, 0xf9, 0x55, 0x1b, 0x11, 0x2d, + 0x11, 0x55, 0xc2, 0xa2, 0x12, 0xd5, 0x7a, 0xcc, 0x71, 0x95, 0x36, 0xf4, 0x67, 0x4a, 0xbe, 0x0a, + 0xa7, 0x97, 0xed, 0x80, 0x56, 0xdd, 0x80, 0xba, 0x81, 0x13, 0x3a, 0x8f, 0xa8, 0xe8, 0x54, 0x3c, + 0xfc, 0x8a, 0x3c, 0x24, 0x7f, 0xc3, 0x0e, 0xd8, 0xc2, 0x8c, 0x50, 0x2c, 0x31, 0x28, 0x6a, 0xc4, + 0xff, 0x6c, 0x2e, 0xc4, 0x84, 0xa9, 0x7a, 0x7d, 0x6d, 0xc5, 0xb1, 0xa3, 0x75, 0x35, 0x89, 0xfd, + 0xf5, 0x2a, 0x3e, 0x2e, 0x05, 0x7b, 0x56, 0xd3, 0xb1, 0xa3, 0x05, 0xd5, 0xa3, 0xb3, 0x12, 0x1c, + 0x8c, 0xc3, 0x1c, 0x94, 0x92, 0x43, 0x49, 0x3e, 0x80, 0x31, 0xee, 0xb9, 0x42, 0x83, 0x3d, 0xa1, + 0x7f, 0x91, 0x8e, 0x10, 0x11, 0x5c, 0x27, 0x12, 0x51, 0xa7, 0xb8, 0x5f, 0x0c, 0x55, 0xed, 0x65, + 0xd7, 0x3e, 0x65, 0xc6, 0xcc, 0x48, 0x13, 0x26, 0xf8, 0x68, 0x51, 0xcc, 0x2a, 0x91, 0x08, 0x9c, + 0xa1, 0x16, 0x25, 0xf8, 0x73, 0x2b, 0x71, 0x3e, 0x27, 0x38, 0x82, 0x56, 0x85, 0xc6, 0x75, 0x09, + 0xa0, 0x28, 0x09, 0x8d, 0xb3, 0x70, 0xa6, 0xc7, 0x37, 0x1b, 0x8f, 0x50, 0xe7, 0xdc, 0xa3, 0x46, + 0xf2, 0x01, 0xcc, 0x21, 0xe1, 0xb2, 0xe7, 0xba, 0xb4, 0x11, 0xe2, 0x76, 0x24, 0xdf, 0x7f, 0x0b, + 0xdc, 0xd6, 0x95, 0xb7, 0xb7, 0x11, 0x21, 0x58, 0xc9, 0x67, 0xe0, 0x4c, 0x0e, 0xc6, 0xff, 0x99, + 0x87, 0x79, 0xb1, 0xc3, 0x99, 0xb4, 0xe1, 0xa1, 0xf6, 0xf1, 0x19, 0x3f, 0x51, 0x57, 0xb5, 0x13, + 0xf5, 0xc5, 0x28, 0x7c, 0x6e, 0x56, 0x23, 0xfb, 0x78, 0x67, 0x6e, 0x25, 0xbc, 0x33, 0x8f, 0x61, + 0xc4, 0x93, 0x02, 0xce, 0x4b, 0xc1, 0xad, 0x97, 0x9f, 0xa6, 0x51, 0x85, 0xe2, 0x5d, 0x7a, 0x80, + 0x0e, 0x58, 0xac, 0x7f, 0xc3, 0xf8, 0xe6, 0x56, 0x94, 0xee, 0xf8, 0x26, 0xfe, 0x4b, 0xca, 0x30, + 0x8c, 0xee, 0x5c, 0x6a, 0xf0, 0x1c, 0x04, 0x98, 0xfc, 0x3f, 0xe3, 0x7f, 0xcf, 0xc1, 0xd9, 0x0d, + 0xdb, 0xed, 0xda, 0xad, 0xbb, 0xf4, 0x80, 0xe7, 0x1a, 0x6d, 0xf3, 0x21, 0xde, 0x71, 0x76, 0xc9, + 0x35, 0x18, 0x15, 0xe9, 0xa8, 0x90, 0x7f, 0x91, 0x6b, 0xf4, 0xd3, 0x19, 0xaa, 0x24, 0x16, 0xb9, + 0x0b, 0xe3, 0x8a, 0xa7, 0xb9, 0xf0, 0x5a, 0x94, 0x3d, 0x2f, 0xbf, 0x59, 0x78, 0x69, 0x66, 0x7b, + 0xa4, 0xdb, 0xb1, 0x47, 0xfa, 0x3d, 0x98, 0x90, 0xda, 0x2e, 0xe4, 0x56, 0xc8, 0xe6, 0xb6, 0x10, + 0xeb, 0xc8, 0x53, 0x9e, 0xe7, 0xe3, 0x02, 0x8e, 0xfe, 0xe6, 0xff, 0x3c, 0x07, 0x17, 0x92, 0x3d, + 0x1f, 0x07, 0x8d, 0xf8, 0xa8, 0x4d, 0x3e, 0x80, 0x53, 0x6d, 0xec, 0x40, 0x8c, 0x68, 0xd1, 0x8e, + 0xba, 0x50, 0xec, 0x05, 0xd2, 0x5f, 0xad, 0x67, 0x27, 0xf3, 0xd7, 0xb9, 0x4c, 0x16, 0xea, 0xeb, + 0x5c, 0x3b, 0x4d, 0x6f, 0xfc, 0x6c, 0x1e, 0x9e, 0xeb, 0x37, 0x27, 0x23, 0xa5, 0x75, 0x2e, 0x4b, + 0x69, 0x4d, 0x3a, 0x30, 0x8b, 0xfb, 0xc5, 0xf2, 0x1e, 0x6d, 0xec, 0x63, 0x40, 0xa9, 0xbb, 0x7c, + 0xd0, 0xb2, 0x2d, 0x22, 0x5f, 0xcb, 0xb4, 0x88, 0x3c, 0xcd, 0x37, 0xb1, 0x06, 0xf2, 0xe0, 0xb1, + 0xaa, 0xd8, 0x18, 0x98, 0x59, 0xac, 0x09, 0x05, 0x88, 0x13, 0xbe, 0x09, 0x2d, 0xff, 0x2b, 0x3d, + 0xd6, 0x44, 0x72, 0x64, 0x30, 0x40, 0x35, 0x5b, 0x17, 0x73, 0x31, 0x0b, 0x75, 0xe2, 0xc4, 0x50, + 0xa3, 0xdb, 0xb3, 0x5b, 0x78, 0x3a, 0xcd, 0x2d, 0x98, 0x56, 0xf2, 0xce, 0xe1, 0xdc, 0xd2, 0x15, + 0x7f, 0xc9, 0x68, 0x22, 0xfc, 0xe5, 0x2d, 0x41, 0x63, 0x4e, 0x51, 0x15, 0x27, 0x30, 0x7e, 0x2a, + 0x0f, 0xa5, 0x4a, 0x37, 0xdc, 0xab, 0xf9, 0x74, 0x87, 0xfa, 0xd4, 0x6d, 0xd0, 0xef, 0x33, 0xaf, + 0x74, 0xbd, 0x71, 0x03, 0xa9, 0xff, 0xbe, 0x3d, 0x05, 0x73, 0x59, 0x64, 0xac, 0x5f, 0x36, 0x33, + 0xf7, 0x2d, 0xd4, 0x33, 0x7d, 0x33, 0x07, 0x13, 0x75, 0xda, 0xf0, 0xdc, 0xe6, 0x2d, 0x34, 0xc8, + 0x17, 0xbd, 0x63, 0x73, 0x89, 0x9b, 0xc1, 0xad, 0x9d, 0x84, 0xa5, 0xfe, 0xf7, 0x0e, 0xcb, 0x5f, + 0x18, 0x4c, 0xd1, 0xd3, 0xf0, 0xf0, 0xe1, 0x20, 0xc4, 0xf4, 0xbd, 0x51, 0x15, 0xfc, 0x6b, 0x4c, + 0xad, 0x5a, 0xb2, 0x04, 0x93, 0xe2, 0xb4, 0xf3, 0xd4, 0x24, 0x3e, 0x3c, 0x40, 0xb7, 0x2c, 0x48, + 0xd9, 0x1e, 0x68, 0x24, 0xe4, 0x06, 0x14, 0xb6, 0x16, 0x6f, 0x89, 0x51, 0x90, 0x81, 0xe8, 0xb6, + 0x16, 0x6f, 0xa1, 0x36, 0x99, 0x4d, 0xe8, 0xc9, 0xee, 0xa2, 0x66, 0xea, 0xbe, 0xb5, 0x78, 0x8b, + 0xfc, 0x79, 0x38, 0xb5, 0xe2, 0x04, 0xa2, 0x0a, 0x1e, 0x21, 0xa1, 0x89, 0x91, 0x98, 0x46, 0x7a, + 0xac, 0xce, 0xcf, 0x65, 0xae, 0xce, 0x17, 0x9a, 0x11, 0x13, 0x8b, 0x87, 0x5f, 0x68, 0x26, 0x93, + 0x15, 0x65, 0xd7, 0x43, 0x3e, 0x84, 0x29, 0x7c, 0x58, 0xc6, 0xa0, 0x11, 0x98, 0x04, 0x74, 0xb4, + 0x47, 0xcd, 0x9f, 0xc9, 0xac, 0x79, 0x81, 0x1b, 0xa7, 0x61, 0xe8, 0x09, 0x4c, 0x18, 0xaa, 0x29, + 0xcd, 0x34, 0xce, 0xe4, 0x0e, 0x4c, 0x8b, 0xdb, 0xcb, 0xfd, 0x9d, 0xcd, 0x3d, 0xba, 0x62, 0x1f, + 0x08, 0x2b, 0x75, 0x54, 0x88, 0x88, 0x2b, 0x8f, 0xe5, 0xed, 0x58, 0xe1, 0x1e, 0xb5, 0x9a, 0xb6, + 0x26, 0xe7, 0x27, 0x08, 0xc9, 0x37, 0x60, 0x7c, 0xdd, 0x6b, 0xb0, 0x8b, 0x2b, 0xee, 0x7c, 0xdc, + 0x70, 0xfd, 0x8b, 0x6c, 0xa3, 0x6a, 0x71, 0x70, 0xe2, 0x36, 0xf2, 0xbd, 0xc3, 0xf2, 0x5b, 0x27, + 0x9d, 0x36, 0x4a, 0x05, 0xa6, 0x5a, 0x1b, 0x59, 0x86, 0xe2, 0x43, 0xba, 0xcd, 0x5a, 0xeb, 0x0a, + 0x57, 0x68, 0xb9, 0xea, 0x24, 0x58, 0xb8, 0xb4, 0x88, 0x5f, 0x9a, 0x4b, 0x8b, 0x80, 0x11, 0x1f, + 0x66, 0xb0, 0x7f, 0x6a, 0x76, 0x10, 0x3c, 0xf6, 0xfc, 0x26, 0xe6, 0x61, 0xee, 0x65, 0x13, 0xbf, + 0x98, 0xd9, 0xf9, 0xcf, 0xf1, 0xce, 0xef, 0x28, 0x1c, 0xd4, 0xfb, 0x57, 0x8a, 0x3d, 0xf9, 0x1a, + 0x4c, 0x89, 0x10, 0x94, 0x1b, 0xb7, 0x2a, 0xb8, 0x12, 0x26, 0xb4, 0x40, 0x4e, 0x7a, 0xa1, 0x7c, + 0xec, 0x45, 0x58, 0x14, 0x3d, 0xad, 0xbd, 0x63, 0xeb, 0x56, 0x1b, 0x2a, 0x09, 0xa9, 0xc1, 0xf8, + 0x0a, 0x7d, 0xe4, 0x34, 0x28, 0x46, 0x80, 0x11, 0x0e, 0xd3, 0x32, 0x5a, 0x8f, 0x52, 0xc2, 0x8f, + 0xf3, 0x26, 0x02, 0x78, 0x3c, 0x19, 0xdd, 0xd9, 0x2d, 0x42, 0x24, 0x37, 0xa1, 0x50, 0x5d, 0xa9, + 0x09, 0x7f, 0xe9, 0x99, 0x28, 0xd0, 0x6b, 0x4d, 0x66, 0x63, 0x47, 0x2f, 0x12, 0xa7, 0xa9, 0x79, + 0x5b, 0x57, 0x57, 0x6a, 0x64, 0x07, 0x26, 0xb9, 0x75, 0x24, 0xb5, 0x79, 0xdf, 0x4e, 0xf7, 0xe8, + 0xdb, 0xab, 0x99, 0x7d, 0x3b, 0x2f, 0xac, 0x2e, 0x05, 0xb5, 0x96, 0x5e, 0x5a, 0x65, 0xcb, 0x6e, + 0x84, 0x22, 0xe5, 0xbd, 0x4c, 0x8a, 0xbc, 0xb9, 0x8e, 0x56, 0xf2, 0xe2, 0x46, 0x28, 0x33, 0xe4, + 0x47, 0x59, 0x9a, 0x7b, 0x86, 0x63, 0x48, 0xf3, 0x21, 0x6f, 0xc2, 0xd0, 0xfd, 0xfd, 0xd0, 0x16, + 0x9e, 0xd1, 0xb2, 0x1f, 0x19, 0x48, 0x36, 0x9f, 0x9b, 0xb7, 0xee, 0x6b, 0xa9, 0x03, 0x90, 0x86, + 0x0d, 0xc5, 0x9a, 0xed, 0x37, 0x1f, 0xdb, 0x3e, 0x46, 0x37, 0x9b, 0xd5, 0x58, 0x28, 0x25, 0x7c, + 0x28, 0xf6, 0x04, 0x20, 0x61, 0x1d, 0xa0, 0xb2, 0x20, 0x3f, 0x00, 0x67, 0x03, 0x67, 0xd7, 0xb5, + 0x43, 0x6e, 0x95, 0xba, 0xeb, 0xf9, 0x4e, 0xb8, 0xd7, 0xb6, 0x82, 0xae, 0x13, 0x52, 0x74, 0x51, + 0x9e, 0x8a, 0x2e, 0x5c, 0x75, 0x89, 0x57, 0x91, 0x68, 0x75, 0x86, 0x65, 0x9e, 0x09, 0xb2, 0x0b, + 0xc8, 0x97, 0x60, 0x52, 0xdd, 0x92, 0x83, 0xf9, 0x53, 0x17, 0x0a, 0x97, 0xa6, 0xa2, 0xa3, 0x3a, + 0xb9, 0x85, 0xcb, 0xd4, 0x65, 0xca, 0x19, 0x11, 0xe8, 0xa9, 0xcb, 0x14, 0x5e, 0xc4, 0x84, 0x33, + 0x01, 0x57, 0x0e, 0x76, 0x5d, 0xe7, 0x09, 0x46, 0xd9, 0x14, 0xde, 0x14, 0xf3, 0xa7, 0xb5, 0xa3, + 0xaf, 0x8e, 0x58, 0x5b, 0xf7, 0xaa, 0x1f, 0x6c, 0x05, 0xd4, 0x17, 0x4e, 0x15, 0x73, 0x9c, 0x76, + 0xcb, 0x75, 0x9e, 0xc4, 0x50, 0xae, 0x79, 0xbc, 0x33, 0x54, 0x24, 0xa5, 0x59, 0x73, 0x46, 0xac, + 0x02, 0x31, 0x72, 0x1b, 0xb7, 0x2a, 0xe6, 0x68, 0xad, 0xfa, 0xa0, 0xde, 0xf2, 0x42, 0x63, 0x0f, + 0xe6, 0xb2, 0xb8, 0x92, 0xf9, 0x84, 0x04, 0x1a, 0x8b, 0x9a, 0xe7, 0x60, 0x6c, 0xc7, 0xf1, 0x83, + 0xd0, 0xea, 0x3a, 0x5c, 0x5e, 0x18, 0x36, 0x8b, 0x08, 0xd8, 0x72, 0x9a, 0xe4, 0x2c, 0x14, 0xf1, + 0x81, 0x98, 0x95, 0x15, 0xb0, 0x6c, 0x94, 0xfd, 0xde, 0x72, 0x9a, 0xc6, 0x7f, 0x9b, 0xc3, 0x23, + 0x88, 0xbc, 0x8a, 0xd1, 0xcc, 0x23, 0xe3, 0x2d, 0x7c, 0xbc, 0xb1, 0x3b, 0x89, 0x9c, 0xaa, 0x1c, + 0x85, 0xbc, 0x06, 0x23, 0xb7, 0xec, 0x06, 0x8d, 0x6c, 0x82, 0x10, 0x79, 0x07, 0x21, 0xea, 0x8d, + 0x84, 0xe3, 0xb0, 0xcb, 0x25, 0x5f, 0x9a, 0x95, 0x30, 0xa4, 0x01, 0xdf, 0x3f, 0x97, 0x2b, 0xd2, + 0x0e, 0x08, 0x2f, 0x97, 0x62, 0x49, 0xdb, 0x31, 0x42, 0xc2, 0x29, 0x36, 0x93, 0x83, 0xf1, 0x47, + 0xb9, 0x78, 0x4f, 0x25, 0xaf, 0xc0, 0x90, 0x59, 0x8b, 0xbe, 0x9f, 0x07, 0x06, 0x4b, 0x7c, 0x3e, + 0x22, 0x90, 0x2f, 0xc1, 0x29, 0x85, 0x4f, 0xca, 0x43, 0xf7, 0x65, 0x8c, 0x5b, 0xa5, 0x7c, 0x49, + 0xb6, 0x9b, 0x6e, 0x36, 0x0f, 0xbc, 0x49, 0xc7, 0x05, 0x2b, 0xd4, 0x75, 0x38, 0x6f, 0xa5, 0xb1, + 0x2a, 0xef, 0x26, 0x22, 0x24, 0x1b, 0x9b, 0xc5, 0x81, 0x87, 0xad, 0x32, 0x7e, 0x23, 0xa7, 0xed, + 0x95, 0xe4, 0xa2, 0x26, 0xc5, 0xe3, 0xba, 0x4e, 0x68, 0xd4, 0xb8, 0x3c, 0xff, 0x06, 0x40, 0xa5, + 0x1b, 0x7a, 0xab, 0xae, 0xef, 0xb5, 0x5a, 0xc2, 0x60, 0x9c, 0x5f, 0xb5, 0xba, 0xa1, 0x67, 0x51, + 0x04, 0x6b, 0x01, 0x71, 0x22, 0xe4, 0x4c, 0x67, 0xe6, 0xc2, 0x47, 0x75, 0x66, 0x66, 0xf7, 0x12, + 0x6d, 0x7b, 0xf8, 0x0c, 0xc8, 0x49, 0xaf, 0x7a, 0x68, 0x74, 0x9c, 0x47, 0x56, 0xd0, 0xf2, 0xb4, + 0xb0, 0xab, 0x02, 0x8d, 0xfc, 0xe5, 0x1c, 0x9c, 0xe6, 0x5e, 0xc1, 0xf7, 0xba, 0xed, 0x6d, 0xea, + 0x3f, 0xb0, 0x5b, 0x4e, 0x33, 0xce, 0x15, 0x11, 0xbb, 0x00, 0x29, 0xd5, 0x64, 0xe3, 0x73, 0x2d, + 0x15, 0xf7, 0x52, 0xb6, 0x5c, 0x2c, 0xb4, 0x1e, 0x45, 0xa5, 0xaa, 0x96, 0x2a, 0x9b, 0x9e, 0x54, + 0x61, 0xbc, 0xe6, 0xb8, 0x98, 0x72, 0x3b, 0x8e, 0xa3, 0xf3, 0x0a, 0x77, 0xf2, 0x67, 0x53, 0xb8, + 0xb1, 0x47, 0xfb, 0x6c, 0xdd, 0x2a, 0xad, 0xf1, 0xab, 0x39, 0x78, 0xe1, 0xd8, 0x0f, 0x66, 0x37, + 0xd0, 0xd5, 0x81, 0x6e, 0xa0, 0x32, 0x27, 0xf4, 0x97, 0xe1, 0x94, 0xca, 0x6a, 0xd3, 0xb7, 0x1d, + 0x35, 0x9e, 0x41, 0x46, 0x07, 0x84, 0x0c, 0x25, 0x29, 0xb6, 0x66, 0x33, 0x31, 0xfe, 0xdf, 0x1c, + 0x8c, 0x45, 0x0e, 0x91, 0xcf, 0xe8, 0x75, 0xe6, 0xa6, 0x76, 0x9d, 0x91, 0x49, 0x77, 0xa2, 0x56, + 0x71, 0xbb, 0xbd, 0x8c, 0x07, 0x91, 0x69, 0xc5, 0x7d, 0x14, 0x01, 0x3f, 0x92, 0x87, 0x71, 0xb6, + 0x55, 0x73, 0x83, 0x90, 0xef, 0xaf, 0xd4, 0x23, 0x51, 0xbb, 0x06, 0x4a, 0x0e, 0xf1, 0xaf, 0x73, + 0xf8, 0x50, 0xa8, 0x52, 0xb0, 0xde, 0x60, 0x20, 0xb5, 0x37, 0xd8, 0x89, 0x6a, 0x22, 0x94, 0x87, + 0xca, 0x5f, 0x17, 0x3d, 0x21, 0x42, 0xe5, 0xb7, 0x4c, 0x06, 0x23, 0x5f, 0x80, 0xe1, 0x2d, 0x7c, + 0xf6, 0xd0, 0xc3, 0x87, 0x46, 0xfc, 0xb1, 0x90, 0xef, 0xf7, 0xdd, 0x40, 0xcf, 0xa3, 0xc0, 0x09, + 0x49, 0x1d, 0x46, 0x97, 0x7d, 0x6a, 0x87, 0xb4, 0x29, 0x3a, 0x64, 0xa0, 0x88, 0x74, 0x0d, 0x4e, + 0x92, 0x8c, 0x48, 0x27, 0x38, 0xb1, 0x7d, 0x8c, 0xc4, 0x6d, 0x44, 0x93, 0xb7, 0xe0, 0x99, 0x1d, + 0xf4, 0xf7, 0xb4, 0x41, 0x3f, 0x9f, 0x1a, 0x74, 0xde, 0xbc, 0x81, 0xc6, 0xfe, 0x37, 0x73, 0x70, + 0x3a, 0x9b, 0x90, 0xbc, 0x08, 0x23, 0xf7, 0x37, 0x6b, 0xb1, 0x99, 0x29, 0x36, 0xc5, 0xeb, 0xa0, + 0x52, 0xc8, 0x14, 0x45, 0xe4, 0x0a, 0x8c, 0xbc, 0x6f, 0x2e, 0xc7, 0xd6, 0x94, 0xb8, 0xc1, 0x7d, + 0x9d, 0x49, 0x5e, 0xda, 0xa9, 0x26, 0x90, 0xd4, 0xb1, 0x2d, 0x3c, 0xb5, 0xb1, 0xfd, 0x89, 0x3c, + 0x4c, 0x57, 0x1a, 0x0d, 0x1a, 0x04, 0x22, 0xd5, 0xe3, 0x33, 0x3b, 0xb0, 0xd9, 0x01, 0x5f, 0xb5, + 0xb6, 0x0d, 0x34, 0xaa, 0xbf, 0x9d, 0xe3, 0x61, 0xb3, 0x19, 0xd5, 0x23, 0x87, 0x3e, 0xde, 0xdc, + 0xf3, 0x69, 0xb0, 0xe7, 0xb5, 0x9a, 0x03, 0xa7, 0x1a, 0x67, 0x32, 0x23, 0xa6, 0x43, 0x54, 0xad, + 0x83, 0x76, 0x10, 0xa2, 0xc9, 0x8c, 0x3c, 0x65, 0xe2, 0x35, 0x18, 0xad, 0x74, 0x3a, 0xbe, 0xf7, + 0x88, 0x2f, 0x7b, 0x91, 0x29, 0xc5, 0xe6, 0x20, 0x2d, 0x06, 0x1f, 0x07, 0xb1, 0xcf, 0x58, 0xa1, + 0xee, 0x81, 0x6a, 0xdb, 0xd9, 0xa4, 0xae, 0x7a, 0x29, 0xc1, 0x72, 0xa3, 0x0e, 0xa4, 0xe6, 0x7b, + 0x6d, 0x2f, 0xa4, 0x4d, 0xde, 0x1e, 0x0c, 0x5d, 0x78, 0x6c, 0x94, 0xf9, 0x4d, 0x27, 0x6c, 0x69, + 0x51, 0xe6, 0x43, 0x06, 0x30, 0x39, 0x9c, 0x9d, 0xdd, 0xe7, 0xb5, 0x3e, 0x5d, 0xf1, 0x0f, 0xcc, + 0xae, 0xbb, 0xea, 0xfa, 0x4e, 0x63, 0x0f, 0xbd, 0xec, 0xef, 0x01, 0x98, 0xd4, 0x0e, 0x3c, 0x57, + 0x11, 0xd6, 0xae, 0xf2, 0x44, 0xeb, 0x0c, 0x9a, 0xd6, 0x3b, 0xcc, 0x08, 0x4e, 0x31, 0x95, 0xa9, + 0x70, 0x20, 0x15, 0x98, 0xe4, 0xbf, 0x58, 0x63, 0x3a, 0x91, 0x20, 0x7e, 0x8e, 0xfb, 0xbc, 0x23, + 0xcb, 0x0e, 0x96, 0xe8, 0xf1, 0x70, 0x14, 0x0a, 0xe3, 0xff, 0x1a, 0x86, 0x09, 0x75, 0x48, 0x89, + 0xc1, 0xb3, 0x06, 0x7b, 0xbe, 0x1a, 0x41, 0xd4, 0x46, 0x88, 0x29, 0x4a, 0xe2, 0xf0, 0xbb, 0xf9, + 0x63, 0xc3, 0xef, 0x3e, 0x84, 0xc9, 0x9a, 0xef, 0x61, 0x1e, 0x1a, 0x34, 0xd5, 0x10, 0xfb, 0xf7, + 0xac, 0xa2, 0x35, 0x60, 0xb3, 0x0f, 0x8d, 0x41, 0xf0, 0x5e, 0xd6, 0x11, 0xd8, 0x16, 0x13, 0x7d, + 0x35, 0x9d, 0x99, 0xc6, 0x87, 0xdb, 0x99, 0xb1, 0x96, 0xa8, 0xd9, 0xd5, 0x78, 0xa3, 0x75, 0x3b, + 0x33, 0x06, 0x51, 0x37, 0x88, 0xe1, 0xa7, 0xb5, 0x41, 0x90, 0x9f, 0xcd, 0xc1, 0x78, 0xc5, 0x75, + 0x45, 0x58, 0xdf, 0x63, 0x82, 0x10, 0x7e, 0x59, 0x98, 0x9a, 0xbd, 0xf5, 0x91, 0x4c, 0xcd, 0x50, + 0xd8, 0x0a, 0x50, 0x52, 0x8f, 0x2b, 0xd4, 0x42, 0x73, 0xc5, 0x60, 0xf2, 0x16, 0x94, 0xa2, 0x95, + 0x59, 0x75, 0x9b, 0xf4, 0x09, 0x0d, 0xe6, 0x47, 0x2f, 0x14, 0x2e, 0x4d, 0x8a, 0xe4, 0x76, 0xaa, + 0x64, 0x9e, 0x44, 0x24, 0x9b, 0x00, 0x76, 0xb4, 0x24, 0xc4, 0x0b, 0xf8, 0xd9, 0xf8, 0xb5, 0x32, + 0xb1, 0x66, 0xe4, 0x43, 0x0d, 0xfb, 0x8d, 0xaf, 0xf9, 0xfa, 0x43, 0x4d, 0xb4, 0xb4, 0xda, 0x30, + 0x5d, 0x09, 0x82, 0x6e, 0x9b, 0xd6, 0x43, 0xdb, 0x0f, 0x31, 0x83, 0x2d, 0x0c, 0x6e, 0x43, 0x6d, + 0x23, 0x29, 0x9b, 0x11, 0x7e, 0x68, 0x65, 0xa4, 0xb3, 0x4d, 0xf2, 0xe6, 0xa9, 0x04, 0xcd, 0x33, + 0xe9, 0xef, 0xe5, 0x2b, 0xf5, 0x27, 0x72, 0x70, 0x5a, 0x9d, 0xf4, 0xf5, 0xee, 0xb6, 0xc8, 0xdf, + 0x43, 0xae, 0xc2, 0x98, 0x98, 0x93, 0xd1, 0x25, 0x32, 0x9d, 0x88, 0x37, 0x46, 0x21, 0xab, 0x6c, + 0x1a, 0x32, 0x1e, 0xe2, 0xd6, 0x31, 0x9b, 0xd8, 0x5c, 0x59, 0x11, 0xbe, 0xd7, 0x89, 0x4c, 0xc2, + 0xec, 0xb7, 0x3e, 0x3f, 0x19, 0xc4, 0x78, 0x17, 0x66, 0xf4, 0x91, 0xa8, 0xd3, 0x90, 0x5c, 0x86, + 0x51, 0x39, 0x7c, 0xb9, 0xec, 0xe1, 0x93, 0xe5, 0xc6, 0x43, 0x20, 0x29, 0xfa, 0x00, 0x6d, 0x42, + 0xd9, 0xfd, 0x9c, 0x3f, 0x5d, 0x48, 0x8b, 0x8c, 0x14, 0xe2, 0xd2, 0xac, 0xf8, 0xbe, 0x71, 0xcd, + 0x59, 0x19, 0x73, 0x19, 0x7d, 0x8b, 0xc0, 0x6c, 0xc6, 0x41, 0x71, 0x8c, 0x20, 0x57, 0xd6, 0x37, + 0x88, 0xb1, 0x28, 0x86, 0xa9, 0xdc, 0x16, 0xde, 0x85, 0xe1, 0x63, 0xb7, 0x03, 0xee, 0x04, 0x9f, + 0xd8, 0x05, 0x38, 0xd9, 0x27, 0x22, 0xcc, 0xa9, 0x31, 0x8b, 0x87, 0x9f, 0x5a, 0xcc, 0x62, 0x0c, + 0x5a, 0xa6, 0x6c, 0xe2, 0x7a, 0x20, 0x35, 0x9e, 0x58, 0x3a, 0xb5, 0x6d, 0xe9, 0x24, 0x9c, 0x47, + 0xe0, 0xb5, 0x1e, 0x51, 0xc1, 0x63, 0x54, 0xe5, 0x81, 0x05, 0x99, 0x3c, 0x14, 0x12, 0xf2, 0x77, + 0x72, 0x40, 0x04, 0x44, 0xdd, 0xb3, 0x8a, 0xfd, 0xf6, 0xac, 0xe6, 0xd3, 0xd9, 0xb3, 0xce, 0xcb, + 0x6f, 0xcc, 0xde, 0xbb, 0x32, 0x3e, 0x8b, 0xfc, 0xad, 0x1c, 0xcc, 0xf0, 0x58, 0xb7, 0xea, 0xc7, + 0xf6, 0x8d, 0x5f, 0xda, 0x78, 0x3a, 0x1f, 0xfb, 0x9c, 0x48, 0x29, 0x9e, 0xfd, 0xad, 0xe9, 0x8f, + 0x22, 0x3f, 0x00, 0x10, 0xad, 0x28, 0x9e, 0xcf, 0x69, 0x7c, 0xf1, 0xb9, 0x8c, 0x5d, 0x20, 0x42, + 0x8a, 0xf3, 0xe8, 0x86, 0x11, 0x9d, 0xba, 0x6d, 0xc6, 0xdc, 0xc8, 0x9f, 0xe7, 0xd9, 0x57, 0x22, + 0x88, 0x08, 0xf3, 0x3d, 0x3f, 0x8e, 0xb5, 0x7c, 0xb6, 0xb7, 0x20, 0x77, 0x35, 0x8b, 0x8c, 0x67, + 0xff, 0x8a, 0x3c, 0x14, 0xfc, 0xb0, 0x9d, 0xcc, 0xc0, 0x92, 0xa4, 0xc0, 0xe8, 0xf9, 0xf8, 0xf5, + 0x3c, 0xd7, 0x6d, 0x8f, 0xfd, 0xed, 0xac, 0x5c, 0x0b, 0x7c, 0x7f, 0x4b, 0x78, 0xf2, 0x21, 0x88, + 0xbc, 0x0f, 0x24, 0x0a, 0x12, 0xcb, 0x61, 0x54, 0xe6, 0xc1, 0xe5, 0x8f, 0x05, 0x71, 0xb0, 0x59, + 0x5f, 0x16, 0xab, 0x93, 0x24, 0x4d, 0x4c, 0x28, 0xcc, 0x89, 0x46, 0x33, 0x28, 0xf7, 0xbe, 0xaf, + 0xae, 0x04, 0xf3, 0x53, 0x5a, 0x10, 0xf5, 0xb8, 0x64, 0xe9, 0x79, 0x99, 0x36, 0x3e, 0x72, 0xe3, + 0xd7, 0xfd, 0xe1, 0x33, 0xd9, 0x91, 0x9b, 0x30, 0x86, 0xc1, 0x8e, 0xd6, 0xa4, 0xa5, 0xab, 0xb0, + 0xba, 0xc3, 0xb0, 0x48, 0xd6, 0x9e, 0x6e, 0xaf, 0x1a, 0xa3, 0xb2, 0x3b, 0x0c, 0x97, 0x00, 0x51, + 0xa5, 0x2f, 0x94, 0x34, 0x4d, 0xff, 0xc0, 0xf2, 0xbb, 0x7a, 0x20, 0x2d, 0x44, 0x22, 0x5f, 0x83, + 0xf1, 0x0d, 0xfb, 0x49, 0x94, 0x9e, 0x7e, 0x66, 0xf0, 0x24, 0xf8, 0x6d, 0xfb, 0x49, 0x94, 0x9b, + 0x3e, 0xe9, 0xfd, 0xa7, 0xb0, 0x24, 0x5f, 0x01, 0x50, 0xde, 0x19, 0xc8, 0xb1, 0x15, 0xbc, 0x20, + 0x53, 0x03, 0x64, 0xbe, 0x3f, 0x20, 0x7f, 0x85, 0x61, 0x42, 0x72, 0x98, 0xfb, 0xe4, 0x24, 0x87, + 0x53, 0x9f, 0x9c, 0xe4, 0xc0, 0x9f, 0xb9, 0xf8, 0xd8, 0xe3, 0x0e, 0x7e, 0x20, 0xb4, 0xfc, 0xfd, + 0x6a, 0x93, 0x66, 0x07, 0x25, 0x3c, 0x0a, 0x0e, 0x12, 0x55, 0x24, 0xf8, 0x11, 0x1f, 0x4a, 0xc9, + 0x8b, 0xc1, 0xfc, 0x19, 0xcd, 0x2c, 0xb7, 0xef, 0x25, 0x82, 0xab, 0x5b, 0xc5, 0x34, 0xb2, 0x68, + 0x04, 0x57, 0x85, 0xba, 0xd4, 0xc5, 0xe3, 0x01, 0x8c, 0x0b, 0x76, 0x78, 0x39, 0x9d, 0xd7, 0x2c, + 0x34, 0xb5, 0xea, 0x58, 0xb9, 0xb0, 0x97, 0x11, 0x87, 0x53, 0xe2, 0xea, 0xaa, 0x32, 0x22, 0x6d, + 0x28, 0xad, 0x7b, 0xee, 0xee, 0x26, 0xf5, 0xdb, 0x18, 0xf6, 0x82, 0xed, 0x4d, 0x67, 0x35, 0x07, + 0x14, 0x59, 0xac, 0x45, 0xc7, 0x70, 0xdc, 0x5d, 0xde, 0x8c, 0x96, 0xe7, 0xee, 0x5a, 0x21, 0xf5, + 0xdb, 0x3c, 0x9e, 0x86, 0x6e, 0x14, 0x98, 0x62, 0xbd, 0xb0, 0x0d, 0x67, 0x7b, 0xee, 0x6b, 0x19, + 0x69, 0xd8, 0xae, 0xe9, 0x69, 0xd8, 0xce, 0xf6, 0x92, 0x7f, 0x02, 0x3d, 0x17, 0xf5, 0x6c, 0x69, + 0xae, 0xb7, 0xe8, 0xf8, 0xdd, 0x7c, 0x42, 0x1e, 0x12, 0x57, 0xd5, 0x0b, 0x90, 0xef, 0x23, 0x30, + 0xe6, 0xab, 0x2b, 0xec, 0x6e, 0x8a, 0x12, 0x93, 0x92, 0x39, 0x93, 0x49, 0x4c, 0xaa, 0xc4, 0x85, + 0xb2, 0xd3, 0xc7, 0x15, 0x8d, 0xde, 0x86, 0xa9, 0x3a, 0xb5, 0xfd, 0xc6, 0xde, 0x5d, 0x7a, 0xf0, + 0xd8, 0xf3, 0x9b, 0x3c, 0xc3, 0xbb, 0xb8, 0x20, 0x05, 0x58, 0xa2, 0x87, 0x6d, 0x51, 0x71, 0xc9, + 0x8a, 0x0c, 0x44, 0x34, 0x8c, 0xb5, 0x9f, 0xcd, 0x3c, 0x62, 0x18, 0x42, 0xbf, 0x18, 0x45, 0xe4, + 0xf5, 0x48, 0x8a, 0xa6, 0xbe, 0x9a, 0x91, 0xda, 0x97, 0xc0, 0x0c, 0x61, 0x9a, 0xfa, 0xc6, 0xef, + 0x17, 0x80, 0xf0, 0x9a, 0x96, 0xed, 0x8e, 0x8d, 0xa1, 0xbf, 0x1c, 0x8c, 0xef, 0x5d, 0x12, 0x38, + 0xf6, 0x76, 0x8b, 0xaa, 0xc1, 0xf1, 0x85, 0xdb, 0x47, 0x54, 0x66, 0x25, 0x6f, 0xa1, 0x29, 0xc2, + 0x1e, 0xe7, 0x50, 0xfe, 0xe3, 0x9c, 0x43, 0x5f, 0x83, 0x73, 0x95, 0x4e, 0xa7, 0xe5, 0x34, 0xa2, + 0x5a, 0x6e, 0x79, 0xbe, 0x9c, 0xf0, 0x5a, 0x3c, 0x14, 0x3b, 0x42, 0x4b, 0x7d, 0x69, 0x3f, 0x16, + 0x8a, 0x10, 0xc9, 0xef, 0xed, 0x6a, 0x90, 0x42, 0xb9, 0x4e, 0xb3, 0x6e, 0xfa, 0x0a, 0x89, 0xe4, + 0xe1, 0xf8, 0x52, 0x88, 0x1c, 0x8e, 0x53, 0x9d, 0xc9, 0x87, 0xfa, 0x6c, 0x41, 0x34, 0x22, 0x21, + 0x6f, 0xc3, 0x78, 0xa5, 0x1b, 0x7a, 0x82, 0xb1, 0xf0, 0x57, 0x8a, 0x3d, 0x8b, 0xc4, 0xa7, 0x68, + 0xf7, 0xd2, 0x18, 0xdd, 0xf8, 0xc3, 0x02, 0x9c, 0x4d, 0x0f, 0xaf, 0x28, 0x8d, 0xd6, 0x47, 0xee, + 0x98, 0xf5, 0x91, 0x35, 0x1b, 0xf2, 0x71, 0x2e, 0xde, 0xa7, 0x31, 0x1b, 0x78, 0xd8, 0xb1, 0x8f, + 0x38, 0x1b, 0xea, 0x6c, 0xaf, 0x8d, 0x85, 0x91, 0xa1, 0x8f, 0x2a, 0x8c, 0xa8, 0x5c, 0xc8, 0x65, + 0x18, 0xe6, 0xb1, 0x19, 0x87, 0xe3, 0x77, 0xcd, 0x64, 0x58, 0x46, 0x8e, 0x41, 0xfe, 0x23, 0xb8, + 0xc0, 0xf7, 0xa4, 0x64, 0x63, 0x97, 0x0e, 0x24, 0x47, 0x31, 0x70, 0x8b, 0x47, 0x87, 0xe5, 0xab, + 0x5c, 0xf9, 0x66, 0xa5, 0xba, 0xcd, 0xda, 0x3e, 0xb0, 0xe4, 0x97, 0x29, 0x95, 0x1c, 0xcb, 0xdb, + 0x78, 0x02, 0x67, 0xe5, 0x11, 0x11, 0x05, 0xd5, 0x92, 0x85, 0x6c, 0x90, 0xf7, 0x63, 0xfd, 0x29, + 0x0e, 0x72, 0xe2, 0x7c, 0xc1, 0x72, 0x72, 0x03, 0x8a, 0x95, 0x5a, 0x15, 0x37, 0x7e, 0x35, 0xfe, + 0x9a, 0xdd, 0x71, 0xf8, 0x49, 0xa1, 0x45, 0x38, 0x11, 0x88, 0x98, 0x99, 0x2e, 0xee, 0x34, 0x72, + 0x25, 0xcb, 0x85, 0x94, 0xe7, 0x53, 0xe4, 0x60, 0xdd, 0x7b, 0x54, 0xaa, 0x76, 0xf3, 0x99, 0xaa, + 0x5d, 0xa9, 0x1b, 0x2c, 0x64, 0xea, 0x06, 0x57, 0x60, 0xba, 0xde, 0xdd, 0x96, 0x75, 0x27, 0x03, + 0xe0, 0x04, 0xdd, 0xed, 0xac, 0xae, 0x4c, 0x92, 0x18, 0x3f, 0x9a, 0x87, 0x89, 0x5a, 0xab, 0xbb, + 0xeb, 0xb8, 0x2b, 0x76, 0x68, 0x3f, 0xb3, 0xda, 0xe6, 0x37, 0x34, 0x6d, 0x73, 0xe4, 0x29, 0x1d, + 0x35, 0x6c, 0x20, 0x55, 0xf3, 0xcf, 0xe4, 0x60, 0x3a, 0x26, 0xe1, 0x27, 0xfc, 0x1a, 0x0c, 0xb1, + 0x1f, 0x42, 0x9d, 0x71, 0x21, 0xc5, 0x18, 0xb1, 0xae, 0x46, 0x7f, 0x09, 0xfd, 0xaf, 0xad, 0xdb, + 0xb7, 0xb0, 0xe2, 0x85, 0xcf, 0xc1, 0x58, 0xcc, 0x36, 0x2d, 0x38, 0xcc, 0xa9, 0x82, 0xc3, 0x98, + 0x9a, 0xa8, 0xf5, 0xd7, 0x72, 0x50, 0x4a, 0xb6, 0x84, 0xdc, 0x85, 0x51, 0xc6, 0xc9, 0xa1, 0x52, + 0xd3, 0xf2, 0x52, 0x8f, 0x36, 0x5f, 0x15, 0x68, 0xfc, 0xf3, 0xb0, 0xf3, 0x29, 0x87, 0x98, 0x92, + 0xc3, 0x82, 0x09, 0x13, 0x2a, 0x56, 0xc6, 0xd7, 0xbd, 0xa6, 0x8b, 0x35, 0xa7, 0xb3, 0xfb, 0x41, + 0xfd, 0xea, 0xbf, 0xae, 0x7d, 0xb5, 0x90, 0x58, 0x2e, 0x6a, 0x93, 0x2b, 0x73, 0x29, 0xe2, 0xa4, + 0xc1, 0x8c, 0xb1, 0x62, 0xdf, 0xc8, 0xab, 0x31, 0x75, 0x53, 0x13, 0x3a, 0xc2, 0x23, 0xaf, 0xc1, + 0x08, 0xaf, 0x4f, 0xcc, 0x33, 0x94, 0x3d, 0x3a, 0x08, 0x51, 0x6f, 0x3e, 0x1c, 0xc7, 0xf8, 0x1b, + 0x05, 0x38, 0x1d, 0x7f, 0xde, 0x56, 0xa7, 0x69, 0x87, 0xb4, 0x66, 0xfb, 0x76, 0x3b, 0x38, 0x66, + 0x05, 0x5c, 0x4a, 0x7d, 0x9a, 0x08, 0xad, 0xc2, 0x61, 0xca, 0x07, 0x19, 0x89, 0x0f, 0x42, 0xad, + 0x36, 0xff, 0x20, 0xf9, 0x19, 0xe4, 0x2e, 0x14, 0xea, 0x34, 0x14, 0x1b, 0xf6, 0xc5, 0x54, 0xaf, + 0xaa, 0xdf, 0x75, 0xb5, 0x4e, 0x43, 0x3e, 0x88, 0x3c, 0x5a, 0xb1, 0x16, 0xc4, 0x84, 0x71, 0x21, + 0x0f, 0x61, 0x64, 0xf5, 0x49, 0x87, 0x36, 0x42, 0x4c, 0x51, 0xa7, 0x44, 0xf3, 0xc8, 0xe6, 0xc7, + 0x71, 0x39, 0xcb, 0x39, 0x71, 0x95, 0xd0, 0xd3, 0xf1, 0x0a, 0x76, 0x0b, 0x37, 0xa1, 0x28, 0x2b, + 0x3f, 0xc9, 0xcc, 0x5d, 0x78, 0x03, 0xc6, 0x95, 0x4a, 0x4e, 0x34, 0xe9, 0x7f, 0x9e, 0xed, 0xab, + 0x5e, 0x8b, 0x8a, 0x89, 0xb3, 0x9a, 0x12, 0x30, 0x95, 0x24, 0xff, 0x5c, 0xc0, 0xb4, 0xf6, 0x45, + 0x51, 0x1f, 0x49, 0xb3, 0x0a, 0xd3, 0xf5, 0x7d, 0xa7, 0x13, 0x67, 0x34, 0xd2, 0x8e, 0x71, 0x4c, + 0x24, 0x2e, 0x54, 0x31, 0xc9, 0x63, 0x3c, 0x49, 0x67, 0xfc, 0xfb, 0x1c, 0x8c, 0xb0, 0xbf, 0x1e, + 0xdc, 0x7c, 0x46, 0xb7, 0xcc, 0x1b, 0xda, 0x96, 0x39, 0xa3, 0x64, 0x28, 0xc4, 0x8d, 0xe3, 0xe6, + 0x31, 0x9b, 0xe5, 0xa1, 0x18, 0x20, 0x8e, 0x4c, 0x6e, 0xc3, 0xa8, 0x30, 0xf1, 0x13, 0xae, 0x4c, + 0x6a, 0xca, 0x43, 0x69, 0xfc, 0x17, 0xe9, 0x6c, 0xbc, 0x4e, 0x52, 0xc9, 0x25, 0xa9, 0xd9, 0x65, + 0x40, 0xe6, 0x96, 0x52, 0xf3, 0x58, 0x33, 0x36, 0xcb, 0x9e, 0xcb, 0x13, 0xf6, 0x05, 0x4b, 0x67, + 0x04, 0xa7, 0x5e, 0xc1, 0xca, 0x2a, 0xe2, 0x51, 0xae, 0xd0, 0x8f, 0xc9, 0x69, 0xc1, 0x24, 0xfb, + 0xbd, 0xae, 0x0d, 0xa7, 0xeb, 0xf5, 0x35, 0x34, 0x07, 0xae, 0x79, 0x7e, 0x78, 0xcb, 0xf3, 0x1f, + 0x8b, 0x98, 0x4c, 0x75, 0xdd, 0x14, 0x26, 0xcb, 0x48, 0xf3, 0x95, 0x4c, 0x23, 0xcd, 0x3e, 0xe6, + 0x32, 0x86, 0x0b, 0x67, 0xea, 0xf5, 0x35, 0x9e, 0x2e, 0xef, 0x4f, 0xa2, 0xbe, 0x5f, 0xcb, 0xc1, + 0x4c, 0xbd, 0xbe, 0x96, 0xa8, 0x6a, 0x5d, 0xe6, 0xe9, 0xcb, 0x69, 0xef, 0xf1, 0xd9, 0x1d, 0x81, + 0xa3, 0x90, 0xe3, 0x62, 0x61, 0x43, 0xcb, 0xb6, 0xc0, 0x99, 0x90, 0x5a, 0x94, 0x19, 0x30, 0xaf, + 0xb9, 0xb7, 0xf5, 0x68, 0x68, 0xec, 0x63, 0xc4, 0xb3, 0x07, 0xea, 0x6f, 0x16, 0x0c, 0x62, 0xfc, + 0xd6, 0x69, 0x9e, 0x7b, 0x50, 0xce, 0x96, 0x77, 0x60, 0x42, 0xd0, 0xa3, 0x0f, 0x98, 0x30, 0x4d, + 0x3a, 0xcb, 0x36, 0xc8, 0x1d, 0x0e, 0xe7, 0x69, 0xa4, 0xbe, 0x77, 0x58, 0x1e, 0x62, 0x5d, 0x63, + 0x6a, 0xe8, 0xe4, 0x3e, 0x4c, 0x6e, 0xd8, 0x4f, 0x14, 0x05, 0x15, 0xf7, 0xf0, 0xbd, 0xcc, 0x76, + 0x95, 0xb6, 0xfd, 0x64, 0x00, 0x23, 0x58, 0x9d, 0x9e, 0xec, 0xc3, 0x94, 0xde, 0x26, 0x31, 0x03, + 0xd3, 0x23, 0x76, 0x3d, 0x73, 0xc4, 0xce, 0x76, 0x3c, 0x3f, 0xb4, 0x76, 0x22, 0x72, 0x2d, 0xcf, + 0x66, 0x82, 0x35, 0x79, 0x07, 0x66, 0x94, 0x9c, 0x16, 0xb7, 0x3c, 0xbf, 0x6d, 0xcb, 0x5b, 0x1a, + 0xbe, 0xda, 0xa0, 0x75, 0xdc, 0x0e, 0x82, 0xcd, 0x34, 0x26, 0xf9, 0x52, 0x96, 0xd7, 0xf4, 0x70, + 0x6c, 0x09, 0x9c, 0xe1, 0x35, 0xdd, 0xcb, 0x12, 0x38, 0xed, 0x3f, 0xbd, 0xdb, 0xcf, 0x53, 0xa0, + 0xc8, 0x5b, 0x3f, 0x90, 0x27, 0x40, 0x34, 0x72, 0x3d, 0x3c, 0x02, 0x16, 0xa1, 0xb0, 0x54, 0xbb, + 0x85, 0x6f, 0x8d, 0xd2, 0x2c, 0xd0, 0xdd, 0xb3, 0xdd, 0x06, 0xde, 0x9e, 0x84, 0x9b, 0x8d, 0x7a, + 0x50, 0x2e, 0xd5, 0x6e, 0x11, 0x1b, 0x66, 0x6b, 0xd4, 0x6f, 0x3b, 0xe1, 0x07, 0xd7, 0xaf, 0x2b, + 0x43, 0x55, 0xc4, 0x4f, 0xbb, 0x26, 0x3e, 0xad, 0xdc, 0x41, 0x14, 0xeb, 0xc9, 0xf5, 0xeb, 0x99, + 0x03, 0x12, 0x7d, 0x58, 0x16, 0x2f, 0x76, 0x60, 0x6d, 0xd8, 0x4f, 0x62, 0x9f, 0xc4, 0x40, 0xc4, + 0x9f, 0x38, 0x2f, 0xa7, 0x56, 0xec, 0xcf, 0xa8, 0x1d, 0x58, 0x3a, 0x11, 0xbb, 0xfc, 0xc6, 0x13, + 0x2c, 0x10, 0x9e, 0xbb, 0x0b, 0x52, 0x01, 0x2b, 0x83, 0x94, 0xa8, 0x37, 0x38, 0x05, 0x9d, 0x6c, + 0x45, 0x57, 0x78, 0x7e, 0x05, 0x46, 0x7b, 0xfd, 0xb1, 0xa5, 0x6b, 0xea, 0x15, 0x9e, 0xab, 0x3d, + 0xb5, 0x66, 0x4d, 0x47, 0x7a, 0x1f, 0xee, 0xa4, 0x69, 0xea, 0x5c, 0xd2, 0x9a, 0x81, 0x89, 0x93, + 0x6b, 0x06, 0x28, 0x0c, 0xad, 0x7b, 0x8d, 0x7d, 0x11, 0x32, 0xfe, 0x7d, 0xb6, 0x0b, 0xb7, 0xbc, + 0xc6, 0xfe, 0xd3, 0xf3, 0x80, 0x40, 0xf6, 0xe4, 0x1e, 0x8f, 0xc0, 0xe5, 0x37, 0x45, 0x9f, 0x08, + 0xab, 0xfa, 0xb9, 0xe8, 0x6a, 0xac, 0x94, 0xc5, 0x71, 0xb9, 0xfc, 0xa6, 0xec, 0x5a, 0x53, 0x27, + 0x27, 0x14, 0x4a, 0x2b, 0x34, 0xd8, 0x0f, 0xbd, 0xce, 0x72, 0xcb, 0xe9, 0x60, 0x50, 0x3b, 0x91, + 0x73, 0x6c, 0xe0, 0x3d, 0xb9, 0xc9, 0xe9, 0xad, 0x86, 0x64, 0x60, 0xa6, 0x58, 0x92, 0x2f, 0xc1, + 0x14, 0x9b, 0xdc, 0xab, 0x4f, 0x42, 0xea, 0xf2, 0x91, 0x9f, 0x41, 0x89, 0x6e, 0x4e, 0xc9, 0xd8, + 0x1b, 0x15, 0xf2, 0x39, 0x85, 0x8b, 0x9d, 0x46, 0x04, 0x5a, 0xb8, 0x7d, 0x8d, 0x15, 0x69, 0xc2, + 0xfc, 0x86, 0xfd, 0x24, 0xbe, 0x28, 0xab, 0x93, 0x94, 0xe0, 0x04, 0xbb, 0x74, 0x74, 0x58, 0x7e, + 0x89, 0x4d, 0xb0, 0x38, 0x0d, 0x5e, 0x8f, 0xf9, 0xda, 0x93, 0x13, 0xf9, 0x06, 0x9c, 0x11, 0xcd, + 0x5a, 0x71, 0x7c, 0x74, 0x3b, 0x3a, 0xa8, 0xef, 0xd9, 0xe8, 0x8e, 0x3c, 0xdb, 0xa3, 0xc3, 0xae, + 0x65, 0x6f, 0x89, 0xb2, 0xc3, 0x9a, 0x92, 0x8f, 0x15, 0x70, 0x46, 0x66, 0xaf, 0x1a, 0xc8, 0x87, + 0x30, 0xc5, 0x1f, 0x58, 0xd7, 0xbc, 0x20, 0x44, 0x0d, 0xcf, 0xdc, 0xc9, 0xdc, 0x84, 0xf8, 0xab, + 0x2d, 0x77, 0x1c, 0x4c, 0x68, 0x84, 0x12, 0x9c, 0xc9, 0x5b, 0x68, 0x89, 0xcb, 0x13, 0x62, 0x54, + 0x6b, 0xf8, 0x50, 0x20, 0x4e, 0xa0, 0x8e, 0xe3, 0x5a, 0x52, 0xcd, 0xd2, 0x89, 0xb6, 0x0b, 0x15, + 0x9b, 0x3c, 0x84, 0xf1, 0x7a, 0x7d, 0xed, 0x96, 0xc3, 0xe4, 0x92, 0x8e, 0xd4, 0xfb, 0xa7, 0xbf, + 0xf2, 0xc5, 0xcc, 0xaf, 0x9c, 0x0c, 0x82, 0x3d, 0x6b, 0xc7, 0x69, 0x51, 0xab, 0xe1, 0x75, 0x0e, + 0x4c, 0x95, 0x53, 0x86, 0xeb, 0xcc, 0x99, 0xa7, 0xec, 0x3a, 0x53, 0x85, 0x69, 0xc5, 0x1c, 0x1c, + 0xad, 0x8b, 0xe6, 0xe3, 0x00, 0xc0, 0xaa, 0xab, 0x4c, 0x32, 0xd2, 0x42, 0x92, 0x4e, 0xfa, 0xcc, + 0x9c, 0x3d, 0xa9, 0xcf, 0x8c, 0x03, 0x33, 0x7c, 0x30, 0xc4, 0x3c, 0xc0, 0x91, 0x5e, 0xe8, 0xd1, + 0x87, 0x97, 0x33, 0xfb, 0x70, 0x56, 0x8c, 0xb4, 0x9c, 0x64, 0x68, 0x50, 0x90, 0xe6, 0x4a, 0x76, + 0x80, 0x08, 0xa0, 0x1d, 0xda, 0xdb, 0x76, 0x40, 0xb1, 0xae, 0x73, 0x3d, 0xea, 0x7a, 0x29, 0xb3, + 0xae, 0x29, 0x59, 0xd7, 0x36, 0xaf, 0x26, 0x83, 0x23, 0x71, 0x65, 0x3d, 0x72, 0x7e, 0x61, 0xc7, + 0x3e, 0xa7, 0x29, 0xc6, 0xd3, 0x08, 0xdc, 0x5b, 0x37, 0x39, 0x69, 0x93, 0xfd, 0x9e, 0xc1, 0x99, + 0x3c, 0x81, 0xd3, 0xe9, 0xaf, 0xc0, 0x3a, 0xcf, 0x63, 0x9d, 0xe7, 0xb5, 0x3a, 0x93, 0x48, 0x7c, + 0xde, 0xe8, 0xcd, 0x4a, 0xd6, 0xda, 0x83, 0x3f, 0xf9, 0xe1, 0x1c, 0x9c, 0xd9, 0xb8, 0x55, 0x79, + 0x40, 0x7d, 0x2e, 0x96, 0x38, 0x9e, 0x1b, 0x45, 0xa8, 0x78, 0x5e, 0x3c, 0x9e, 0x24, 0xdf, 0xbf, + 0xa4, 0xc4, 0x81, 0x5b, 0x05, 0x13, 0xdd, 0x5f, 0x6c, 0xef, 0xd8, 0xd6, 0x23, 0x85, 0x45, 0x46, + 0x18, 0x8b, 0x6f, 0xff, 0x41, 0x39, 0x67, 0xf6, 0xaa, 0x8a, 0xb4, 0x60, 0x41, 0xef, 0x16, 0xe9, + 0xd5, 0xb4, 0x47, 0x5b, 0xad, 0xf9, 0x32, 0xce, 0xe8, 0xd7, 0x8e, 0x0e, 0xcb, 0x97, 0x52, 0xbd, + 0x1b, 0x79, 0x4a, 0x31, 0x4c, 0xa5, 0xc1, 0x7d, 0xf8, 0x91, 0x76, 0x86, 0xd0, 0x3d, 0x7f, 0x41, + 0x0b, 0x65, 0x97, 0x2a, 0x8f, 0x42, 0x2d, 0x9e, 0x67, 0xeb, 0xbd, 0xa7, 0x80, 0x68, 0xa6, 0x39, + 0xdf, 0x19, 0x2a, 0x4e, 0x96, 0xa6, 0x32, 0xdc, 0x7d, 0x8c, 0xef, 0xe4, 0x13, 0x07, 0x23, 0xa9, + 0xc2, 0xa8, 0x98, 0xef, 0x3d, 0x2f, 0x19, 0xe7, 0x33, 0x67, 0xf5, 0xa8, 0x58, 0x3a, 0xa6, 0xa4, + 0x27, 0x8f, 0x19, 0x2b, 0x6c, 0xb4, 0xb8, 0xf1, 0x7e, 0x85, 0x9f, 0x7b, 0x08, 0xd2, 0x4e, 0xf8, + 0x95, 0x93, 0xbb, 0xc6, 0xea, 0x0e, 0xd4, 0x78, 0xd4, 0xcb, 0xda, 0xc8, 0x3e, 0x4f, 0xa0, 0x5e, + 0x88, 0xbc, 0x2b, 0xf5, 0x6c, 0xe9, 0x4f, 0xad, 0x42, 0x56, 0x8b, 0xf1, 0x1b, 0x39, 0x98, 0xd4, + 0x4e, 0x56, 0x72, 0x53, 0x71, 0x1e, 0x8e, 0x9f, 0x3a, 0x35, 0x1c, 0xdc, 0x6c, 0x93, 0x6e, 0xc5, + 0x37, 0x95, 0x20, 0xae, 0x3d, 0xe8, 0x70, 0xb1, 0x25, 0x3d, 0xe5, 0xfb, 0xeb, 0x87, 0xcb, 0x30, + 0xcc, 0xa3, 0x78, 0x0d, 0xc5, 0xb6, 0xa3, 0xa8, 0x5f, 0x31, 0x39, 0xdc, 0xf8, 0xc3, 0x32, 0x4c, + 0xe9, 0x37, 0x62, 0xf2, 0x1a, 0x8c, 0xa0, 0x42, 0x5f, 0xaa, 0x57, 0x50, 0x2d, 0x84, 0x3a, 0x7f, + 0xcd, 0xbd, 0x8a, 0xe3, 0x90, 0x97, 0x01, 0x22, 0x3f, 0x04, 0xf9, 0x9c, 0x35, 0x7c, 0x74, 0x58, + 0xce, 0x5d, 0x31, 0x95, 0x02, 0xf2, 0x55, 0x80, 0x7b, 0x5e, 0x93, 0x8a, 0x7c, 0xc0, 0x85, 0x7e, + 0xf6, 0x34, 0xaf, 0xa4, 0xf2, 0x01, 0x9f, 0x72, 0xbd, 0x26, 0x4d, 0x27, 0xff, 0x55, 0x38, 0x92, + 0x37, 0x61, 0xd8, 0xec, 0xb6, 0xa8, 0x7c, 0xf6, 0x18, 0x97, 0x27, 0x5c, 0xb7, 0x45, 0x63, 0x3d, + 0x81, 0xdf, 0x4d, 0x9a, 0x8a, 0x32, 0x00, 0x79, 0x8f, 0xe7, 0x09, 0x16, 0x49, 0x17, 0x86, 0xe3, + 0x07, 0x3e, 0x45, 0xf2, 0x49, 0xa5, 0x5d, 0x50, 0x48, 0xc8, 0x7d, 0x18, 0x55, 0x5f, 0xa6, 0x94, + 0x10, 0x2e, 0xea, 0xeb, 0xa5, 0xa2, 0x74, 0x10, 0xd1, 0xa7, 0x93, 0x8f, 0x56, 0x92, 0x0b, 0x79, + 0x1b, 0xc6, 0x18, 0x7b, 0xb6, 0x73, 0x04, 0xe2, 0x56, 0x83, 0xcf, 0x78, 0xca, 0x07, 0xb1, 0xdd, + 0x47, 0x4b, 0x8d, 0x10, 0x11, 0x90, 0x2f, 0xc1, 0x58, 0xa5, 0xd3, 0x11, 0x5d, 0xdd, 0xd7, 0xce, + 0xea, 0x62, 0xaa, 0xab, 0xe7, 0xec, 0x4e, 0x27, 0xdd, 0xd3, 0x31, 0x3f, 0xb2, 0x1b, 0x45, 0x10, + 0x1d, 0x24, 0xb7, 0xf3, 0xab, 0xa9, 0x0a, 0xe6, 0x65, 0x50, 0xcc, 0x54, 0x25, 0x3a, 0x5f, 0xd2, + 0x81, 0x52, 0x2c, 0x54, 0x8a, 0xba, 0xa0, 0x5f, 0x5d, 0x57, 0x52, 0x75, 0xa9, 0x03, 0x98, 0xaa, + 0x2e, 0xc5, 0x9d, 0x34, 0x61, 0x4a, 0x1e, 0x50, 0xa2, 0xbe, 0xf1, 0x7e, 0xf5, 0xbd, 0x9c, 0xaa, + 0x6f, 0xb6, 0xb9, 0x9d, 0xae, 0x27, 0xc1, 0x93, 0xbc, 0x0d, 0x93, 0x12, 0x82, 0xeb, 0x03, 0xed, + 0x9b, 0x84, 0x42, 0xb0, 0xb9, 0x8d, 0x9e, 0x4f, 0x5a, 0xaf, 0x68, 0xc8, 0x2a, 0x35, 0x9f, 0x1d, + 0x93, 0x1a, 0x75, 0x72, 0x56, 0xe8, 0xc8, 0xe4, 0x8b, 0x30, 0x5e, 0x6d, 0xb3, 0x86, 0x78, 0xae, + 0x1d, 0x52, 0xe1, 0x9f, 0x2c, 0x6d, 0xc6, 0x94, 0x12, 0x65, 0xaa, 0xa2, 0xb5, 0x8c, 0x13, 0x17, + 0xa9, 0xd7, 0x4c, 0x85, 0x82, 0x75, 0x1e, 0x7f, 0x8a, 0x14, 0x73, 0x58, 0xfa, 0x2e, 0x9f, 0xcf, + 0xb0, 0xdb, 0x52, 0xd8, 0x8b, 0x00, 0xfb, 0x0c, 0x2a, 0x9f, 0x02, 0x13, 0xc9, 0x4d, 0x54, 0x9e, + 0xe4, 0x1d, 0x18, 0x17, 0x69, 0xef, 0x2b, 0xe6, 0xbd, 0x60, 0xbe, 0x14, 0x9b, 0x9d, 0xcb, 0x0c, + 0xf9, 0x96, 0xed, 0x27, 0x0c, 0x94, 0x63, 0x7c, 0xf2, 0x01, 0xcc, 0x3d, 0x74, 0xdc, 0xa6, 0xf7, + 0x38, 0x10, 0xc7, 0x94, 0xd8, 0xe8, 0x66, 0x62, 0xf7, 0xc8, 0xc7, 0xbc, 0x3c, 0x92, 0x05, 0x53, + 0x1b, 0x5f, 0x26, 0x07, 0xf2, 0x43, 0x29, 0xce, 0x7c, 0x06, 0x91, 0x7e, 0x33, 0x68, 0x31, 0x35, + 0x83, 0xd2, 0xd5, 0x27, 0xa7, 0x53, 0x66, 0x35, 0xc4, 0x03, 0xa2, 0x9f, 0xef, 0x77, 0x3c, 0xc7, + 0x9d, 0x9f, 0xc5, 0xbd, 0xf0, 0x5c, 0x32, 0x8a, 0x09, 0xe2, 0xd5, 0xbc, 0x96, 0xd3, 0x38, 0xe0, + 0x29, 0xae, 0x92, 0x32, 0xff, 0x87, 0x9e, 0xf6, 0x5c, 0x92, 0xc1, 0x9a, 0x7c, 0x11, 0x26, 0xd8, + 0xff, 0x91, 0x52, 0x62, 0x4e, 0xb3, 0xf4, 0x55, 0x30, 0x45, 0x3d, 0x38, 0x46, 0x98, 0x97, 0x3f, + 0x43, 0x5f, 0xa1, 0xb1, 0x22, 0x6f, 0x00, 0x30, 0xb1, 0x49, 0x6c, 0xc7, 0xa7, 0xe2, 0x5c, 0x32, + 0x28, 0x75, 0xa5, 0x37, 0xe2, 0x18, 0x99, 0xbc, 0x0d, 0xe3, 0xec, 0x57, 0xbd, 0xdb, 0xf4, 0xd8, + 0xda, 0x38, 0x8d, 0xb4, 0xdc, 0x55, 0x9c, 0xd1, 0x06, 0x1c, 0xae, 0xb9, 0x8a, 0xc7, 0xe8, 0x64, + 0x0d, 0xa6, 0x31, 0xe7, 0x8f, 0xc8, 0x36, 0xe1, 0xd0, 0x60, 0xfe, 0x8c, 0x62, 0x42, 0x81, 0xb9, + 0xa9, 0x9d, 0xa8, 0x4c, 0xbd, 0xcb, 0x24, 0xc8, 0x48, 0x00, 0xb3, 0xe9, 0x37, 0xe8, 0x60, 0x7e, + 0x1e, 0x3b, 0x49, 0x4a, 0xf0, 0x69, 0x0c, 0xbe, 0x1f, 0xb3, 0x11, 0x51, 0x36, 0x2e, 0xf9, 0xa8, + 0xa4, 0x56, 0x98, 0xc5, 0x9d, 0x98, 0x40, 0x6e, 0x2f, 0xd7, 0x92, 0x49, 0x71, 0xce, 0x62, 0x0b, + 0x70, 0x98, 0x77, 0x1b, 0x1d, 0xab, 0x4f, 0x62, 0x9c, 0x0c, 0x6a, 0xf2, 0x83, 0x70, 0x4a, 0xee, + 0x20, 0xa2, 0x48, 0xcc, 0xeb, 0x85, 0x13, 0xee, 0xc4, 0xcd, 0xed, 0xa8, 0xea, 0xd4, 0x94, 0xce, + 0xae, 0x82, 0xd8, 0x30, 0x8e, 0xc3, 0x2a, 0x6a, 0x3c, 0xd7, 0xaf, 0xc6, 0x4b, 0xa9, 0x1a, 0x4f, + 0xe3, 0x44, 0x49, 0x57, 0xa6, 0xf2, 0x24, 0x4b, 0x30, 0x29, 0xd6, 0x91, 0x98, 0x6d, 0xcf, 0x61, + 0x6f, 0xa1, 0x12, 0x4b, 0xae, 0xc0, 0xd4, 0x84, 0xd3, 0x49, 0xd4, 0x1d, 0x99, 0x3f, 0x26, 0x9d, + 0xd7, 0x76, 0xe4, 0xe4, 0x1b, 0x92, 0x8e, 0xcc, 0x76, 0xa4, 0x58, 0x8a, 0x59, 0x7d, 0xd2, 0xf1, + 0x85, 0x8a, 0xea, 0xf9, 0x38, 0xcd, 0xaf, 0x22, 0xfc, 0x58, 0x34, 0xc2, 0x50, 0xb7, 0x84, 0x2c, + 0x0e, 0x64, 0x0b, 0x66, 0xa3, 0x53, 0x5b, 0x61, 0x5c, 0x8e, 0xd3, 0xae, 0xc4, 0x47, 0x7d, 0x36, + 0xdf, 0x2c, 0x7a, 0x62, 0xc3, 0x19, 0xed, 0x9c, 0x56, 0x58, 0x5f, 0x40, 0xd6, 0xaf, 0xb0, 0x1b, + 0x99, 0x7e, 0xc8, 0x67, 0xb3, 0xef, 0xc5, 0x87, 0x7c, 0x08, 0x0b, 0xc9, 0xb3, 0x59, 0xa9, 0xe5, + 0x05, 0xac, 0xe5, 0xd5, 0xa3, 0xc3, 0xf2, 0xc5, 0xd4, 0xf1, 0x9e, 0x5d, 0x51, 0x1f, 0x6e, 0xe4, + 0xab, 0x30, 0xaf, 0x9f, 0xcf, 0x4a, 0x4d, 0x06, 0xd6, 0x84, 0x4b, 0x27, 0x3a, 0xd8, 0xb3, 0x6b, + 0xe8, 0xc9, 0x83, 0x84, 0x50, 0xce, 0x9c, 0xdd, 0x4a, 0x35, 0x2f, 0xc6, 0x0d, 0x4a, 0xad, 0x92, + 0xec, 0xea, 0x8e, 0x63, 0x49, 0x1e, 0xc3, 0xf3, 0x59, 0xc7, 0x84, 0x52, 0xe9, 0x4b, 0x91, 0x12, + 0xf8, 0xd3, 0xd9, 0x47, 0x4e, 0x76, 0xcd, 0xc7, 0xb0, 0x25, 0x5f, 0x82, 0x53, 0xca, 0xfa, 0x52, + 0xea, 0x7b, 0x19, 0xeb, 0xc3, 0xe0, 0x06, 0xea, 0xc2, 0xcc, 0xae, 0x25, 0x9b, 0x07, 0x69, 0xc3, + 0xac, 0x6c, 0x38, 0x6a, 0xdb, 0xc5, 0xd1, 0x73, 0x51, 0xdb, 0x55, 0xd3, 0x18, 0x4b, 0x17, 0xc4, + 0xae, 0x3a, 0xdf, 0xdc, 0xb6, 0x3a, 0x31, 0xa1, 0x3a, 0xd3, 0x33, 0xf8, 0x92, 0x35, 0x18, 0xa9, + 0xd7, 0xaa, 0xb7, 0x6e, 0xad, 0xce, 0xbf, 0x82, 0x35, 0x48, 0xf7, 0x45, 0x0e, 0xd4, 0x2e, 0x4d, + 0xc2, 0xc6, 0xb1, 0xe3, 0xec, 0xec, 0x68, 0x0f, 0x56, 0x1c, 0x95, 0xfc, 0x10, 0x5a, 0x17, 0xb2, + 0x1d, 0xb5, 0x12, 0x04, 0xce, 0xae, 0xcb, 0x13, 0xda, 0xbc, 0xaa, 0xbd, 0xf7, 0xcb, 0x14, 0x47, + 0xcb, 0x98, 0x81, 0x3b, 0x85, 0xce, 0xa5, 0x4d, 0x76, 0xff, 0x17, 0x3b, 0xb7, 0x65, 0xc7, 0xac, + 0xd4, 0x4d, 0x3c, 0x5d, 0x11, 0xeb, 0xb7, 0x5d, 0x27, 0xb4, 0xf6, 0xba, 0x5a, 0xf3, 0xe7, 0x3f, + 0xad, 0xc5, 0x15, 0xe3, 0x79, 0xc9, 0x95, 0x5e, 0x7b, 0x49, 0x54, 0xf8, 0x1c, 0xbf, 0x2d, 0xf7, + 0xe8, 0xb9, 0x99, 0xdd, 0x04, 0x5d, 0x40, 0xfe, 0x52, 0x0e, 0x4e, 0x3f, 0xf4, 0xfc, 0xfd, 0x96, + 0x67, 0x37, 0x65, 0xab, 0xc4, 0x1e, 0xfe, 0x5a, 0xbf, 0x3d, 0xfc, 0xb3, 0xa9, 0x3d, 0xdc, 0x78, + 0x2c, 0xd8, 0x58, 0x51, 0x86, 0xa8, 0xd4, 0x7e, 0xde, 0xa3, 0x2a, 0xf2, 0x43, 0x70, 0x21, 0xbb, + 0x44, 0x99, 0x94, 0x57, 0x70, 0x52, 0x5e, 0x3f, 0x3a, 0x2c, 0x5f, 0xe9, 0x55, 0x53, 0xf6, 0x04, + 0x3d, 0x96, 0x35, 0x79, 0x13, 0x0a, 0x1b, 0xcb, 0xb5, 0xf9, 0xab, 0xda, 0xd3, 0xf3, 0xc6, 0x72, + 0x4d, 0xe9, 0x28, 0xae, 0xd1, 0x6c, 0x37, 0x34, 0x8d, 0xe6, 0xc6, 0x72, 0xed, 0xce, 0x50, 0xf1, + 0x52, 0xe9, 0xf2, 0x9d, 0xa1, 0xe2, 0xe5, 0xd2, 0xab, 0xe6, 0x73, 0xf5, 0xca, 0xc6, 0x7a, 0xb5, + 0x29, 0x0f, 0x66, 0x99, 0x00, 0x8b, 0xd7, 0x67, 0x5e, 0xec, 0x57, 0x1a, 0x7f, 0x8d, 0xf1, 0x57, + 0x73, 0x50, 0x3e, 0x66, 0x82, 0xb1, 0xb3, 0x30, 0xfe, 0xb8, 0x7a, 0x94, 0x74, 0x85, 0xfb, 0x46, + 0x46, 0x05, 0x96, 0x6e, 0x72, 0xa2, 0x93, 0xa0, 0xdf, 0xac, 0xc8, 0xdd, 0xa8, 0xb8, 0x4f, 0xa7, + 0x73, 0x36, 0x4a, 0x2c, 0x63, 0x1d, 0x4a, 0xc9, 0x89, 0x47, 0x3e, 0x0f, 0x93, 0x6a, 0xe6, 0x38, + 0xa9, 0x86, 0xe0, 0x41, 0x83, 0xfc, 0x5d, 0xed, 0x30, 0xd5, 0x10, 0x8d, 0x8b, 0x30, 0xa5, 0x77, + 0x31, 0x99, 0x83, 0xe1, 0xd0, 0xf3, 0x5a, 0x82, 0x87, 0xc9, 0x7f, 0x18, 0x3f, 0x9f, 0x83, 0xd9, + 0x8c, 0x55, 0x4c, 0x2e, 0xc2, 0x10, 0xe6, 0xd1, 0x56, 0x2c, 0x93, 0x12, 0xf9, 0xb3, 0xb1, 0x9c, + 0x7c, 0x06, 0x46, 0x57, 0xee, 0xd5, 0xeb, 0x95, 0x7b, 0x52, 0xe1, 0xc1, 0x0f, 0x7b, 0x37, 0xb0, + 0x02, 0x5b, 0x37, 0x68, 0x10, 0x68, 0xe4, 0x0a, 0x8c, 0x54, 0x6b, 0x48, 0xa0, 0xa4, 0x9f, 0x72, + 0x3a, 0x49, 0x7c, 0x81, 0x64, 0x7c, 0x2b, 0x07, 0x24, 0xbd, 0x25, 0x91, 0xeb, 0x30, 0xae, 0x6e, + 0x7c, 0xbc, 0x5f, 0xf0, 0x95, 0x57, 0x59, 0x9c, 0xa6, 0x8a, 0x43, 0x56, 0x60, 0x18, 0xd3, 0xd2, + 0x46, 0x96, 0x14, 0x99, 0x4b, 0xef, 0x4c, 0x6a, 0xe9, 0x0d, 0x63, 0xaa, 0x5b, 0x93, 0x13, 0x1b, + 0x7f, 0x9c, 0x03, 0x92, 0x6d, 0x54, 0x39, 0x90, 0x25, 0xd7, 0xeb, 0x4a, 0x98, 0x0e, 0xd5, 0xaa, + 0x32, 0x4a, 0x73, 0xae, 0xaa, 0x1a, 0xe2, 0x80, 0x1e, 0x17, 0x35, 0xd5, 0x56, 0x6f, 0xdf, 0xee, + 0xcb, 0x30, 0xfc, 0x80, 0xfa, 0xdb, 0xd2, 0xde, 0x1c, 0x6d, 0x54, 0x1f, 0x31, 0x80, 0xaa, 0xea, + 0x41, 0x0c, 0xcd, 0xbc, 0x73, 0x78, 0x50, 0xf3, 0xce, 0x3f, 0xcc, 0xc1, 0x5c, 0xd6, 0xe5, 0xe9, + 0x18, 0xbf, 0x6d, 0x23, 0xe1, 0x72, 0x8e, 0xa6, 0x5f, 0xdc, 0xea, 0x35, 0x72, 0x34, 0x2f, 0xc3, + 0x30, 0xeb, 0x21, 0x39, 0x2d, 0x50, 0x3f, 0xc7, 0xba, 0x30, 0x30, 0x39, 0x9c, 0x21, 0xc4, 0x59, + 0x83, 0x86, 0x39, 0x02, 0x4f, 0x16, 0xc4, 0xe1, 0x0c, 0x61, 0xc3, 0x6b, 0x52, 0xa9, 0xb7, 0x42, + 0x84, 0x36, 0x03, 0x98, 0x1c, 0x4e, 0x2e, 0xc2, 0xe8, 0x7d, 0x77, 0x9d, 0xda, 0x8f, 0x64, 0x76, + 0x42, 0x34, 0x55, 0xf3, 0x5c, 0xab, 0xc5, 0x60, 0xa6, 0x2c, 0x34, 0x7e, 0x26, 0x07, 0x33, 0xa9, + 0x7b, 0xdb, 0xf1, 0xae, 0xe9, 0xfd, 0xdd, 0x2d, 0x07, 0x69, 0x1f, 0xff, 0xfc, 0xa1, 0xec, 0xcf, + 0x37, 0xfe, 0xfb, 0x11, 0x38, 0xd3, 0x43, 0x8d, 0x16, 0xbb, 0x83, 0xe7, 0x8e, 0x75, 0x07, 0xff, + 0x32, 0x4c, 0x2e, 0xb7, 0x6c, 0xa7, 0x1d, 0x6c, 0x7a, 0xf1, 0x17, 0xc7, 0x5e, 0x65, 0x58, 0x26, + 0xbc, 0x3a, 0x22, 0xf7, 0xa3, 0xb3, 0x0d, 0xa4, 0xb0, 0x42, 0x2f, 0x2d, 0xc5, 0x6b, 0xcc, 0x52, + 0x0e, 0xd9, 0x85, 0x3f, 0x25, 0x0e, 0xd9, 0xba, 0x8b, 0xe0, 0xd0, 0x53, 0x75, 0x11, 0xcc, 0xb6, + 0x60, 0x1f, 0xfe, 0x38, 0xfe, 0x0c, 0xcb, 0x30, 0xc9, 0x6d, 0xf5, 0x2a, 0x01, 0x1f, 0xa4, 0x91, + 0x94, 0x7d, 0x9f, 0x1d, 0xa4, 0xc7, 0x42, 0xa3, 0x21, 0x6b, 0xba, 0x3b, 0xdb, 0x28, 0x3e, 0x66, + 0x5f, 0xec, 0xed, 0xae, 0xa6, 0xc7, 0x44, 0x52, 0xdd, 0xd6, 0xbe, 0x01, 0x73, 0x59, 0xf7, 0xf0, + 0xf9, 0xa2, 0x66, 0x06, 0xdc, 0xd3, 0xe6, 0x7c, 0xf0, 0xdb, 0xfc, 0x7e, 0xe6, 0x6d, 0x5e, 0x86, + 0x19, 0x18, 0xeb, 0xed, 0xa3, 0x15, 0xaf, 0x05, 0x8e, 0xdb, 0x3f, 0x18, 0x81, 0xf1, 0xe5, 0x44, + 0x9c, 0x88, 0x24, 0x39, 0x79, 0x4b, 0x0b, 0xe7, 0xf5, 0x4a, 0x3a, 0x9c, 0x57, 0x76, 0x68, 0x08, + 0x9e, 0x68, 0xee, 0x67, 0xf2, 0xba, 0x73, 0xfb, 0x9f, 0xc6, 0x85, 0x7a, 0x19, 0x86, 0x1f, 0xee, + 0x51, 0x5f, 0x9e, 0x29, 0xf8, 0x21, 0x8f, 0x19, 0x40, 0xfd, 0x10, 0xc4, 0x20, 0xb7, 0x60, 0xaa, + 0xc6, 0x27, 0xae, 0x9c, 0x8d, 0x43, 0xb1, 0x32, 0xa8, 0x23, 0x54, 0x96, 0x19, 0xd3, 0x31, 0x41, + 0x65, 0xdc, 0x4e, 0x74, 0xba, 0x08, 0x46, 0xc6, 0xfd, 0xbc, 0xb8, 0xd4, 0x31, 0x15, 0xbb, 0x1d, + 0xc6, 0x9b, 0xad, 0x99, 0x80, 0x1a, 0x3b, 0xf0, 0x7c, 0x5f, 0x46, 0xec, 0xb0, 0x87, 0x4e, 0xf4, + 0x2b, 0x61, 0x12, 0xde, 0x97, 0xd4, 0x54, 0xe8, 0x8c, 0xf5, 0xd8, 0x13, 0xb1, 0xba, 0x82, 0xae, + 0x90, 0x6f, 0xc2, 0x84, 0xea, 0x2b, 0x22, 0x38, 0x67, 0xb8, 0x96, 0x0c, 0xb1, 0x01, 0x31, 0xc7, + 0x25, 0x72, 0xb5, 0x19, 0x18, 0xff, 0xa6, 0x00, 0xf3, 0xbd, 0x7c, 0xf1, 0xc8, 0x4f, 0x46, 0x71, + 0x5d, 0xd0, 0xd1, 0xcd, 0x8b, 0x55, 0x65, 0xbc, 0x8a, 0x37, 0x8f, 0x71, 0xe6, 0xbb, 0x9a, 0x49, + 0xcc, 0xad, 0x99, 0x23, 0x37, 0x17, 0x3c, 0xd8, 0x69, 0xd3, 0xda, 0x3e, 0xb0, 0x14, 0xaf, 0x4f, + 0x33, 0xbb, 0x62, 0xf2, 0x3e, 0x9c, 0x32, 0x69, 0xc3, 0x6b, 0xb7, 0xa9, 0xdb, 0x54, 0xbd, 0xf0, + 0xc4, 0x21, 0x2e, 0x42, 0x9c, 0x44, 0x08, 0x3a, 0xcb, 0x4c, 0x4a, 0x72, 0x0f, 0x66, 0xe2, 0x18, + 0x6a, 0x32, 0x8b, 0x86, 0x92, 0x6c, 0x2a, 0x8e, 0xf9, 0x26, 0x73, 0x68, 0xa8, 0x17, 0xac, 0x14, + 0x29, 0xb9, 0x06, 0xb0, 0x6c, 0xbb, 0x35, 0xdf, 0x6b, 0x50, 0x11, 0x86, 0xa0, 0x28, 0x6c, 0xfd, + 0x6c, 0x8c, 0xbb, 0xc2, 0xc0, 0xa6, 0x82, 0xb2, 0x60, 0xc1, 0x42, 0xef, 0x8e, 0xca, 0xb0, 0xc8, + 0xfe, 0xb4, 0x6e, 0xe8, 0x7f, 0x2a, 0x35, 0xd0, 0x8c, 0x8f, 0x6a, 0xa8, 0xfd, 0x0d, 0x98, 0x50, + 0x17, 0x26, 0x4a, 0x2d, 0xec, 0xb7, 0xd8, 0x48, 0xb8, 0xd4, 0xc2, 0x00, 0x26, 0x87, 0xc7, 0xef, + 0x92, 0xf9, 0xec, 0x77, 0xc9, 0x78, 0xc7, 0x28, 0x1c, 0xb7, 0x63, 0xb0, 0xca, 0xf1, 0x50, 0x54, + 0x2a, 0xc7, 0xdf, 0x6a, 0xe5, 0x18, 0x55, 0xce, 0xe4, 0xf0, 0xa7, 0x5a, 0xf9, 0x3f, 0x91, 0xb9, + 0x6d, 0xd1, 0xf3, 0x50, 0x9d, 0xbd, 0x91, 0xe7, 0x61, 0x7a, 0xc3, 0x8f, 0x31, 0x63, 0xd9, 0x35, + 0x7f, 0xac, 0xec, 0x7a, 0x82, 0xbd, 0x0b, 0xef, 0x61, 0x7c, 0x17, 0x18, 0x8a, 0xef, 0x1b, 0x76, + 0xca, 0x72, 0x4b, 0x62, 0x19, 0xdf, 0xce, 0xc1, 0xa9, 0xcc, 0xf7, 0x1f, 0x56, 0x2b, 0x7f, 0x68, + 0x52, 0xb6, 0xee, 0xe4, 0x2b, 0x13, 0xc7, 0x38, 0x49, 0x74, 0x9e, 0xc1, 0xdb, 0x62, 0xbc, 0x00, + 0x63, 0x91, 0xf5, 0x01, 0xbb, 0xcf, 0xf1, 0xa1, 0xe3, 0xe1, 0x47, 0xc5, 0x23, 0xf6, 0xcf, 0xe7, + 0x00, 0xd8, 0x27, 0x7c, 0x82, 0x7e, 0x02, 0xbc, 0x0f, 0x7a, 0xf8, 0x09, 0x24, 0xfb, 0x23, 0x49, + 0x67, 0xfc, 0x93, 0x3c, 0x8c, 0xb0, 0xbf, 0x9e, 0xd9, 0xa0, 0xeb, 0xd9, 0x7e, 0x02, 0xac, 0x49, + 0x7d, 0x52, 0x4c, 0xac, 0x26, 0x52, 0x4c, 0xcc, 0xaa, 0x64, 0x32, 0xf9, 0x6b, 0x14, 0xa2, 0xa6, + 0x57, 0x4a, 0x09, 0xc5, 0xdd, 0xe0, 0x77, 0x73, 0x30, 0xa1, 0x12, 0x93, 0x2f, 0xc2, 0x94, 0x0c, + 0x24, 0xcd, 0xc3, 0x36, 0x09, 0xb3, 0x0b, 0x69, 0x22, 0x29, 0x03, 0x49, 0xab, 0x61, 0x9e, 0x34, + 0x7c, 0x55, 0x52, 0xe8, 0xa8, 0xc8, 0xa4, 0x09, 0xa4, 0xbd, 0x63, 0x5b, 0x8f, 0xa9, 0xbd, 0x4f, + 0x83, 0xd0, 0xe2, 0xa6, 0x6c, 0xc2, 0x3a, 0x43, 0xb2, 0xdf, 0xb8, 0x55, 0xe1, 0x56, 0x6c, 0xe8, + 0xbc, 0xce, 0x23, 0x82, 0xa7, 0x68, 0xd4, 0x27, 0xe7, 0xf6, 0x8e, 0xfd, 0x90, 0x17, 0x72, 0x3a, + 0xe3, 0x8f, 0x46, 0xf8, 0xcc, 0x15, 0x91, 0xe7, 0xb7, 0x61, 0xea, 0x7e, 0x75, 0x65, 0x59, 0x79, + 0x80, 0xd2, 0x83, 0xff, 0xaf, 0x3e, 0x09, 0xa9, 0xef, 0xda, 0x2d, 0xa9, 0xcb, 0x89, 0x25, 0x20, + 0xcf, 0x69, 0x36, 0xb2, 0x1f, 0xa7, 0x12, 0x1c, 0x59, 0x1d, 0x5c, 0x6b, 0x14, 0xd5, 0x91, 0x1f, + 0xb0, 0x8e, 0xc0, 0x6e, 0xb7, 0x7a, 0xd4, 0xa1, 0x73, 0x24, 0x7b, 0xa8, 0xd6, 0xd9, 0xeb, 0x6e, + 0x2b, 0xb5, 0x14, 0xfa, 0xd7, 0xf2, 0xa2, 0xa8, 0xe5, 0x9c, 0x50, 0x37, 0x66, 0xd6, 0x93, 0xe2, + 0x1a, 0xef, 0x39, 0x43, 0xc7, 0xee, 0x39, 0xff, 0x49, 0x0e, 0x46, 0xf8, 0xed, 0x49, 0x4c, 0xe3, + 0x1e, 0xf7, 0xb3, 0x87, 0x4f, 0xe7, 0x7e, 0x56, 0xc2, 0x33, 0x47, 0x9b, 0xd0, 0xbc, 0x8c, 0xac, + 0x24, 0xd6, 0x05, 0x89, 0xa4, 0x9c, 0x5d, 0xc7, 0x55, 0x32, 0xad, 0xf4, 0x5d, 0x16, 0xa4, 0x1a, + 0x07, 0x0d, 0x1a, 0x3d, 0x36, 0x52, 0x84, 0x0c, 0xb4, 0x34, 0x2a, 0x82, 0x06, 0xe9, 0xa1, 0x82, + 0xd6, 0x61, 0x4c, 0x84, 0x22, 0x5a, 0x3a, 0x10, 0x06, 0x23, 0x25, 0xcd, 0xe4, 0xaf, 0xb9, 0x74, + 0x10, 0xdf, 0x0c, 0x45, 0x30, 0x23, 0x6b, 0x5b, 0x75, 0x97, 0x89, 0x19, 0x90, 0xfb, 0x30, 0x16, + 0x47, 0xe6, 0xd7, 0x33, 0x59, 0x45, 0x70, 0x11, 0x99, 0x51, 0xc6, 0x33, 0xc9, 0x08, 0xc4, 0x1f, + 0xf3, 0x20, 0xeb, 0x50, 0x42, 0x33, 0x51, 0xda, 0xe4, 0xab, 0xa6, 0xba, 0xc2, 0xc3, 0xdd, 0x08, + 0xf1, 0x29, 0xe4, 0x65, 0x62, 0xb9, 0x25, 0x9c, 0x99, 0x53, 0x94, 0xc6, 0x4f, 0xe7, 0xa1, 0x94, + 0x9c, 0x7d, 0xe4, 0x6d, 0x18, 0x8f, 0x32, 0x23, 0x44, 0xe1, 0x14, 0xf0, 0xe1, 0x38, 0x4e, 0xa5, + 0xa0, 0x05, 0x56, 0x50, 0xd1, 0xc9, 0x22, 0x14, 0xd9, 0x22, 0x76, 0xe3, 0xc0, 0xb6, 0xb8, 0x6d, + 0x77, 0x05, 0x4c, 0x55, 0x2a, 0x49, 0x3c, 0x52, 0x87, 0x59, 0xb6, 0x68, 0xea, 0x8e, 0xbb, 0xdb, + 0xa2, 0xeb, 0xde, 0xae, 0xd7, 0x0d, 0xb7, 0xcc, 0x75, 0xb1, 0x87, 0xf3, 0xfb, 0xb3, 0xdd, 0x6e, + 0x69, 0xc5, 0xbe, 0x6a, 0x60, 0x98, 0x45, 0x4d, 0xae, 0xf0, 0x63, 0xa6, 0xba, 0x22, 0xec, 0xbd, + 0xf0, 0xd8, 0x47, 0x3b, 0x45, 0xed, 0xe3, 0x05, 0x92, 0xb2, 0xb3, 0xfe, 0x41, 0x1e, 0xc6, 0x95, + 0xe9, 0x47, 0x2e, 0x43, 0xb1, 0x1a, 0xac, 0x7b, 0x8d, 0xfd, 0x28, 0xd2, 0xef, 0xe4, 0xd1, 0x61, + 0x79, 0xcc, 0x09, 0xac, 0x16, 0x02, 0xcd, 0xa8, 0x98, 0x2c, 0xc1, 0x24, 0xff, 0x4b, 0x4a, 0xb6, + 0xf9, 0x58, 0x6f, 0xcc, 0x91, 0x33, 0xa4, 0x5a, 0x9d, 0x84, 0x7c, 0x05, 0x80, 0x03, 0x30, 0xcc, + 0x4a, 0x61, 0xf0, 0x00, 0x31, 0xa2, 0x82, 0x8c, 0x00, 0x2b, 0x0a, 0x43, 0xf2, 0x35, 0x9e, 0x78, + 0x41, 0x2e, 0x97, 0xa1, 0xc1, 0x23, 0xdc, 0x30, 0xfe, 0x56, 0x76, 0xa0, 0x2d, 0x95, 0xa5, 0x48, + 0xe9, 0xb8, 0x20, 0xf3, 0x77, 0x57, 0x42, 0x44, 0x54, 0x30, 0x8c, 0xff, 0x25, 0xa7, 0x2c, 0x32, + 0x72, 0x0f, 0xc6, 0xa2, 0x09, 0x24, 0x4c, 0x2d, 0xa3, 0x1b, 0xae, 0x84, 0x9b, 0x74, 0x67, 0xe9, + 0x9c, 0xb0, 0xfa, 0x9c, 0x8d, 0xa6, 0xa1, 0xb6, 0xe6, 0x24, 0x90, 0x7c, 0x01, 0x86, 0xb0, 0xeb, + 0xf2, 0xc7, 0x36, 0x4d, 0x9e, 0xf2, 0x43, 0xac, 0xcf, 0xb0, 0x21, 0x48, 0x49, 0x3e, 0x23, 0xa2, + 0x20, 0xf0, 0xce, 0x9f, 0x52, 0x8e, 0x6a, 0xf6, 0x1d, 0xd1, 0xf1, 0x1e, 0xc7, 0x5a, 0x53, 0x66, + 0xcf, 0x5f, 0xcd, 0x43, 0x29, 0xb9, 0xb4, 0xc9, 0x7b, 0x30, 0x21, 0x8f, 0xdf, 0x35, 0x5b, 0x24, + 0x37, 0x9b, 0x10, 0xc9, 0xc5, 0xe4, 0x19, 0xbc, 0x67, 0xab, 0xa6, 0x99, 0xa6, 0x46, 0xc0, 0x64, + 0xa1, 0x4d, 0x11, 0xb0, 0x55, 0x59, 0x54, 0xa1, 0x17, 0x76, 0x12, 0xf1, 0xfe, 0x25, 0x1a, 0x79, + 0x1d, 0x0a, 0x1b, 0xb7, 0x2a, 0xc2, 0xf1, 0xb5, 0x94, 0x3c, 0xa4, 0xc5, 0x7b, 0x8b, 0x66, 0xcf, + 0xce, 0xf0, 0xc9, 0xba, 0x92, 0x1a, 0x63, 0x44, 0x33, 0xc3, 0x95, 0xe0, 0xa8, 0x71, 0xc7, 0xe7, + 0xc8, 0xb8, 0x33, 0x54, 0x2c, 0x94, 0x86, 0x44, 0xb8, 0xf4, 0x7f, 0x51, 0x80, 0xb1, 0xa8, 0x7e, + 0x42, 0xd4, 0x18, 0x04, 0x22, 0xde, 0xc0, 0x59, 0x28, 0x4a, 0xe9, 0x4e, 0xf8, 0xbf, 0x8e, 0x06, + 0x42, 0xb2, 0x9b, 0x07, 0x29, 0xc6, 0xf1, 0x5d, 0xc1, 0x94, 0x3f, 0xc9, 0x75, 0x88, 0x64, 0xb4, + 0x5e, 0xc2, 0x1c, 0xbf, 0x89, 0x47, 0x68, 0x64, 0x0a, 0xf2, 0x0e, 0x0f, 0x41, 0x39, 0x66, 0xe6, + 0x9d, 0x26, 0x79, 0x0f, 0x8a, 0x76, 0x13, 0xef, 0xaf, 0x83, 0xe4, 0x79, 0x2f, 0x32, 0x6e, 0xfc, + 0xcc, 0x40, 0xaa, 0x4a, 0x48, 0x2a, 0x30, 0xc6, 0x63, 0xfa, 0x07, 0xb4, 0x39, 0xc0, 0x01, 0x14, + 0x73, 0xc0, 0x54, 0x00, 0x5b, 0x01, 0x6d, 0x92, 0x57, 0x60, 0x88, 0x8d, 0xa6, 0x38, 0x71, 0xa4, + 0x50, 0xc9, 0x06, 0x93, 0x77, 0xd8, 0xda, 0xa7, 0x4c, 0x44, 0x20, 0x2f, 0x41, 0xa1, 0xbb, 0xb8, + 0x23, 0xce, 0x92, 0x52, 0x9c, 0xa6, 0x26, 0x42, 0x63, 0xc5, 0xe4, 0x06, 0x14, 0x1f, 0xeb, 0x19, + 0x4e, 0x4e, 0x25, 0x86, 0x31, 0xc2, 0x8f, 0x10, 0xc9, 0x2b, 0x50, 0x08, 0x02, 0x4f, 0x18, 0xfa, + 0xcd, 0x46, 0xd6, 0xd7, 0xf7, 0xa3, 0x51, 0x63, 0xdc, 0x83, 0xc0, 0x5b, 0x2a, 0xc2, 0x08, 0x3f, + 0x60, 0x8c, 0xe7, 0x01, 0xe2, 0x6f, 0x4c, 0xdf, 0x9e, 0x8d, 0xaf, 0xc0, 0x58, 0xf4, 0x6d, 0xe4, + 0x3c, 0xc0, 0x3e, 0x3d, 0xb0, 0xf6, 0x6c, 0xb7, 0xd9, 0xe2, 0xd2, 0xe9, 0x84, 0x39, 0xb6, 0x4f, + 0x0f, 0xd6, 0x10, 0x40, 0xce, 0xc0, 0x68, 0x87, 0x0d, 0xbf, 0x98, 0xe3, 0x13, 0xe6, 0x48, 0xa7, + 0xbb, 0xcd, 0xa6, 0xf2, 0x3c, 0x8c, 0xa2, 0x9a, 0x5f, 0xac, 0xc8, 0x49, 0x53, 0xfe, 0x34, 0xfe, + 0x5d, 0x01, 0xb3, 0x68, 0x2a, 0x0d, 0x22, 0x2f, 0xc2, 0x64, 0xc3, 0xa7, 0x78, 0x96, 0xd9, 0x4c, + 0x42, 0x13, 0xf5, 0x4c, 0xc4, 0xc0, 0x6a, 0x93, 0x5c, 0x84, 0xe9, 0x4e, 0x77, 0xbb, 0xe5, 0x34, + 0x30, 0x93, 0x57, 0x63, 0x5b, 0x64, 0x2e, 0x9a, 0x30, 0x27, 0x39, 0xf8, 0x2e, 0x3d, 0x58, 0xde, + 0xc6, 0x18, 0xab, 0x25, 0x35, 0x45, 0x00, 0x66, 0x70, 0xe3, 0xf3, 0x6f, 0x5a, 0x81, 0xa3, 0xcd, + 0xf2, 0x69, 0x18, 0xb1, 0xed, 0xdd, 0xae, 0xc3, 0x95, 0x10, 0x13, 0xa6, 0xf8, 0x45, 0x3e, 0x0d, + 0x33, 0x71, 0xce, 0x0d, 0xd9, 0x8c, 0x61, 0x6c, 0x46, 0x29, 0x2a, 0x58, 0xe6, 0x70, 0x72, 0x05, + 0x88, 0x5a, 0x9f, 0xb7, 0xfd, 0x21, 0x6d, 0xf0, 0x39, 0x39, 0x61, 0xce, 0x28, 0x25, 0xf7, 0xb1, + 0x80, 0xbc, 0x80, 0xba, 0x28, 0x94, 0x0e, 0xb1, 0xdb, 0x30, 0xc9, 0x34, 0xaa, 0x9c, 0x10, 0xc6, + 0xfa, 0xee, 0x12, 0x94, 0x94, 0xee, 0xc0, 0x2c, 0x0c, 0x3c, 0x69, 0x8f, 0x39, 0x15, 0xc3, 0xcd, + 0x4e, 0xb5, 0x49, 0x3e, 0x80, 0x05, 0x05, 0x93, 0xe7, 0xbb, 0xb6, 0x68, 0xcb, 0xd9, 0x75, 0xb6, + 0x5b, 0x54, 0xcc, 0xb7, 0xf4, 0xac, 0x8e, 0xae, 0xa3, 0xe6, 0x7c, 0x4c, 0xcd, 0x33, 0x61, 0xaf, + 0x0a, 0x5a, 0xb2, 0x0e, 0x73, 0x09, 0xce, 0xb4, 0x69, 0x75, 0x3b, 0x3d, 0x83, 0x8f, 0xc6, 0x3c, + 0x89, 0xce, 0x93, 0x36, 0xb7, 0x3a, 0xc6, 0x37, 0x60, 0x42, 0x9d, 0x93, 0xac, 0x13, 0x54, 0xb9, + 0x44, 0xcc, 0xbe, 0xf1, 0x08, 0x56, 0x65, 0xf7, 0xc2, 0xa9, 0x18, 0x05, 0x07, 0x91, 0x6f, 0x2f, + 0x93, 0x11, 0x14, 0x87, 0xf0, 0x05, 0x98, 0x68, 0x3a, 0x41, 0xa7, 0x65, 0x1f, 0xa0, 0xe5, 0xa9, + 0x18, 0xe9, 0x71, 0x01, 0x43, 0xbd, 0xe3, 0x12, 0xcc, 0xa4, 0xf6, 0x41, 0x45, 0xd2, 0xe0, 0xfb, + 0x7a, 0x7f, 0x49, 0xc3, 0x70, 0x61, 0x42, 0x3d, 0xd7, 0x8e, 0x49, 0xb1, 0x75, 0x1a, 0x63, 0x5a, + 0xf1, 0x4d, 0x7f, 0xe4, 0xe8, 0xb0, 0x9c, 0x77, 0x9a, 0x18, 0xc9, 0xea, 0x12, 0x14, 0xa5, 0xc4, + 0x26, 0x04, 0x25, 0x7c, 0xcb, 0x92, 0x4f, 0xf6, 0x66, 0x54, 0x6a, 0xbc, 0x02, 0xa3, 0xe2, 0xe8, + 0xea, 0xff, 0x82, 0x65, 0x7c, 0x33, 0x0f, 0xd3, 0x26, 0x65, 0x1b, 0x2b, 0xe5, 0x49, 0x29, 0x9f, + 0xd9, 0x2b, 0x7a, 0x76, 0xac, 0x6d, 0xad, 0x6d, 0x7d, 0xf2, 0x2b, 0xff, 0x4a, 0x0e, 0x66, 0x33, + 0x70, 0xc9, 0x62, 0x56, 0x2c, 0x1b, 0x8c, 0x33, 0x26, 0x4d, 0xbc, 0xb0, 0x33, 0xb5, 0x80, 0x36, + 0x37, 0x61, 0x6c, 0xc5, 0xb1, 0x5b, 0x95, 0x66, 0x33, 0x0a, 0x70, 0x85, 0x72, 0x3e, 0xe6, 0x4c, + 0xb5, 0x19, 0x54, 0x15, 0x62, 0x22, 0x54, 0xf2, 0xaa, 0x98, 0x14, 0x85, 0xa8, 0x5b, 0x71, 0x52, + 0x7c, 0xef, 0xb0, 0x0c, 0xfc, 0x9b, 0x36, 0xa3, 0x29, 0x82, 0xf1, 0xef, 0x39, 0x30, 0xf6, 0x37, + 0x7c, 0x66, 0x87, 0x2e, 0x3b, 0xfe, 0x7d, 0xb2, 0x79, 0x03, 0x25, 0xb5, 0xfb, 0xf1, 0x3c, 0x9c, + 0xce, 0x26, 0xfc, 0x48, 0x43, 0xf9, 0x1a, 0x8c, 0x61, 0xb2, 0x44, 0x25, 0x67, 0xc7, 0xd4, 0xd1, + 0x61, 0x19, 0x78, 0x66, 0x45, 0xc4, 0x8f, 0x11, 0xc8, 0x0e, 0x4c, 0xae, 0xdb, 0x41, 0xb8, 0x46, + 0x6d, 0x3f, 0xdc, 0xa6, 0x76, 0x38, 0x80, 0x24, 0x2f, 0xad, 0x8c, 0xe6, 0x51, 0x98, 0xd8, 0x93, + 0x94, 0x09, 0x59, 0x5b, 0x67, 0x1b, 0x4d, 0x94, 0xa1, 0x01, 0x26, 0xca, 0xd7, 0x61, 0xba, 0x4e, + 0xdb, 0x76, 0x67, 0xcf, 0xf3, 0x65, 0x1c, 0x91, 0xab, 0x30, 0x19, 0x81, 0x32, 0x67, 0x8b, 0x5e, + 0xac, 0xe1, 0x2b, 0x1d, 0x11, 0x6f, 0x25, 0x7a, 0xb1, 0xf1, 0xd7, 0xf2, 0x70, 0xa6, 0xd2, 0x10, + 0x26, 0xd3, 0xa2, 0x40, 0x7a, 0x76, 0x7c, 0xc2, 0x75, 0x93, 0x6b, 0x30, 0xb6, 0x61, 0x3f, 0x59, + 0xa7, 0x76, 0x40, 0x03, 0x91, 0x10, 0x86, 0x8b, 0xbd, 0xf6, 0x93, 0xf8, 0xed, 0xd1, 0x8c, 0x71, + 0x54, 0x35, 0xc2, 0xd0, 0xc7, 0x54, 0x23, 0x18, 0x30, 0xb2, 0xe6, 0xb5, 0x9a, 0xe2, 0xac, 0x17, + 0x06, 0x0f, 0x7b, 0x08, 0x31, 0x45, 0x89, 0xf1, 0x87, 0x39, 0x98, 0x8a, 0xbe, 0x18, 0x3f, 0xe1, + 0x13, 0xef, 0x92, 0x8b, 0x30, 0x8a, 0x15, 0x55, 0x57, 0xd4, 0x43, 0xa3, 0x45, 0x31, 0x3b, 0x74, + 0xd3, 0x94, 0x85, 0x6a, 0x4f, 0x0c, 0x7f, 0xbc, 0x9e, 0x30, 0xfe, 0x36, 0xda, 0x52, 0xa8, 0xad, + 0x64, 0x27, 0x91, 0xf2, 0x21, 0xb9, 0x01, 0x3f, 0x24, 0xff, 0xd4, 0x86, 0xa4, 0xd0, 0x73, 0x48, + 0x7e, 0x24, 0x0f, 0xe3, 0xd1, 0xc7, 0x7e, 0x9f, 0x25, 0x8e, 0x89, 0xda, 0x35, 0x50, 0xec, 0xaf, + 0xba, 0xb2, 0x57, 0x88, 0x10, 0x5b, 0x5f, 0x80, 0x11, 0xb1, 0x98, 0x72, 0x09, 0x0f, 0x87, 0xc4, + 0xe8, 0x2e, 0x4d, 0x09, 0xd6, 0x23, 0x38, 0xa0, 0x81, 0x29, 0xe8, 0x30, 0xb8, 0xda, 0x43, 0xba, + 0x2d, 0x4c, 0x6b, 0x9e, 0xd9, 0x33, 0x2a, 0x3b, 0xb8, 0x5a, 0xdc, 0xb0, 0x81, 0x4e, 0xa7, 0x7f, + 0x5e, 0x84, 0x52, 0x92, 0xe4, 0xf8, 0xd4, 0x3c, 0xb5, 0xee, 0x36, 0xbf, 0xaa, 0xf0, 0xd4, 0x3c, + 0x9d, 0xee, 0xb6, 0xc9, 0x60, 0x68, 0xae, 0xe7, 0x3b, 0x8f, 0xb0, 0xd5, 0x13, 0xc2, 0x5c, 0xcf, + 0x77, 0x1e, 0x69, 0xe6, 0x7a, 0xbe, 0xf3, 0x08, 0x15, 0x09, 0xeb, 0x75, 0x0c, 0x3c, 0x82, 0xf7, + 0x14, 0xa1, 0x48, 0x68, 0x05, 0xc9, 0x7c, 0xa3, 0x12, 0x8d, 0x1d, 0x95, 0x4b, 0xd4, 0xf6, 0x45, + 0x1a, 0x19, 0xb1, 0x9d, 0xe1, 0x51, 0xb9, 0x8d, 0x60, 0x2b, 0x64, 0x70, 0x53, 0x45, 0x22, 0x2d, + 0x20, 0xca, 0x4f, 0xb9, 0x80, 0x8f, 0xbf, 0x5b, 0x4b, 0xeb, 0xe4, 0x39, 0x95, 0xb5, 0xa5, 0xae, + 0xe6, 0x0c, 0xbe, 0x4f, 0x53, 0xfb, 0x5b, 0x13, 0x61, 0xa6, 0x51, 0x81, 0x54, 0x3c, 0x96, 0x99, + 0x0c, 0x98, 0x04, 0x3c, 0x0c, 0x75, 0xa4, 0x46, 0x8a, 0x99, 0x90, 0x77, 0x61, 0x5c, 0x0d, 0x27, + 0xc3, 0x83, 0x9e, 0x3c, 0xc7, 0x83, 0xd3, 0xc6, 0x71, 0x64, 0x74, 0xc3, 0x1b, 0x35, 0x6e, 0xcc, + 0x36, 0x9c, 0x59, 0xf6, 0xdc, 0xa0, 0xdb, 0x96, 0xcf, 0xe8, 0x71, 0x66, 0x04, 0xc0, 0xa1, 0xc0, + 0xd8, 0x14, 0x0d, 0x81, 0x22, 0x9f, 0xe0, 0x65, 0xd4, 0x11, 0xed, 0x02, 0xd2, 0x8b, 0x11, 0xd9, + 0x84, 0x71, 0xd4, 0xa0, 0x0a, 0x53, 0xe0, 0x71, 0x7d, 0xdb, 0x88, 0x4b, 0x56, 0xd8, 0xc2, 0xe0, + 0xd1, 0x14, 0xed, 0x76, 0x4b, 0x7a, 0x2f, 0xa9, 0x9a, 0x60, 0x05, 0x99, 0x7c, 0x05, 0xa6, 0xf8, + 0x15, 0xed, 0x21, 0xdd, 0xe6, 0x73, 0x67, 0x42, 0xd3, 0x44, 0xe8, 0x85, 0xdc, 0x96, 0x44, 0xe8, + 0xad, 0x1f, 0xd3, 0x6d, 0x3e, 0xf6, 0x9a, 0xef, 0xa0, 0x86, 0x4f, 0xb6, 0x60, 0x76, 0xcd, 0x0e, + 0x38, 0x50, 0x89, 0x0b, 0x32, 0x89, 0x1a, 0x5a, 0xf4, 0xe9, 0xd8, 0xb3, 0x03, 0xa9, 0x08, 0xcf, + 0x8c, 0x03, 0x92, 0x45, 0x4f, 0xbe, 0x99, 0x83, 0x79, 0x4d, 0x4f, 0x2e, 0xcc, 0x1c, 0x31, 0x44, + 0xf4, 0x14, 0x3e, 0x79, 0xc9, 0xb0, 0xca, 0xbd, 0xd0, 0xf8, 0x90, 0x24, 0x54, 0xf1, 0x7e, 0x5c, + 0xae, 0x3a, 0x4b, 0xf4, 0xe2, 0x21, 0x16, 0x2a, 0xae, 0xe9, 0x69, 0x7d, 0xa1, 0x26, 0xd6, 0xb5, + 0x44, 0x33, 0x6e, 0x26, 0xfb, 0x5b, 0x28, 0xba, 0x72, 0x91, 0xa2, 0x0b, 0x2d, 0x80, 0xd9, 0x40, + 0x88, 0xe8, 0x72, 0xf8, 0xc3, 0xf8, 0x8c, 0xba, 0x0f, 0x09, 0xb1, 0xb0, 0xef, 0x3e, 0x64, 0xfc, + 0x4f, 0x23, 0x30, 0x9d, 0x98, 0x16, 0xe2, 0x9e, 0x9a, 0x4b, 0xdd, 0x53, 0xeb, 0x00, 0x5c, 0xd5, + 0x3b, 0xa0, 0x4e, 0x56, 0x3a, 0x28, 0x8f, 0x8b, 0xf0, 0x02, 0xd1, 0x9a, 0x52, 0xd8, 0x30, 0xa6, + 0x7c, 0xc5, 0x0e, 0xa8, 0x23, 0x8f, 0x98, 0xf2, 0x45, 0xaf, 0x30, 0x8d, 0xd9, 0x90, 0x32, 0x0c, + 0x63, 0x30, 0x6a, 0xd5, 0x3f, 0xdc, 0x61, 0x00, 0x93, 0xc3, 0xc9, 0x8b, 0x30, 0xc2, 0x84, 0xa8, + 0xea, 0x8a, 0xd8, 0x04, 0xf1, 0x6c, 0x61, 0x52, 0x16, 0x93, 0x58, 0x44, 0x11, 0xb9, 0x09, 0x13, + 0xfc, 0x2f, 0x11, 0x7e, 0x6a, 0x44, 0x37, 0xd8, 0xb5, 0x9c, 0xa6, 0x8c, 0x40, 0xa5, 0xe1, 0xb1, + 0xdb, 0x45, 0xbd, 0x8b, 0x6a, 0x9d, 0xea, 0x8a, 0x48, 0x2d, 0x81, 0xb7, 0x8b, 0x80, 0x03, 0x59, + 0x15, 0x31, 0x02, 0x93, 0x65, 0x84, 0x97, 0x56, 0x11, 0xef, 0x94, 0x28, 0xcb, 0x70, 0xef, 0x2c, + 0x53, 0x94, 0x90, 0xcb, 0xfc, 0x25, 0x06, 0xc5, 0x42, 0x9e, 0x5f, 0x19, 0xdf, 0x2d, 0x50, 0x31, + 0x81, 0xb2, 0x61, 0x54, 0xcc, 0x2a, 0x67, 0x7f, 0xaf, 0xb6, 0x6d, 0xa7, 0x25, 0xb6, 0x15, 0xac, + 0x1c, 0x71, 0x29, 0x83, 0x9a, 0x31, 0x02, 0x79, 0x1b, 0xa6, 0x78, 0x1e, 0xd4, 0x76, 0xdb, 0x73, + 0x91, 0xfd, 0x78, 0x1c, 0x60, 0x52, 0xe4, 0x66, 0x65, 0x45, 0xbc, 0x96, 0x04, 0x2e, 0x3b, 0x4f, + 0xf0, 0x95, 0xb7, 0xcb, 0xdf, 0x88, 0x26, 0xe2, 0xf3, 0x04, 0x49, 0x03, 0x0e, 0x37, 0x55, 0x24, + 0xf2, 0x06, 0x4c, 0xb2, 0x9f, 0xb7, 0x9d, 0x47, 0x94, 0x57, 0x38, 0x19, 0x9b, 0x4a, 0x20, 0xd5, + 0x2e, 0x2b, 0xe1, 0xf5, 0xe9, 0x98, 0xe4, 0x7d, 0x38, 0x85, 0x9c, 0x1a, 0x5e, 0x87, 0x36, 0x2b, + 0x3b, 0x3b, 0x4e, 0xcb, 0xe1, 0xc6, 0x90, 0x53, 0xb1, 0x0d, 0x13, 0xaf, 0x18, 0x31, 0x2c, 0x3b, + 0x46, 0x31, 0xb3, 0x29, 0xc9, 0x43, 0x28, 0x2d, 0x77, 0x83, 0xd0, 0x6b, 0x57, 0xc2, 0xd0, 0x77, + 0xb6, 0xbb, 0x21, 0x0d, 0xe6, 0xa7, 0xb5, 0x70, 0x44, 0x6c, 0x71, 0x44, 0x85, 0x5c, 0x1f, 0xd4, + 0x40, 0x0a, 0xcb, 0x8e, 0x48, 0xcc, 0x14, 0x13, 0xe3, 0x7f, 0xcc, 0xc1, 0xa4, 0x46, 0x4a, 0x5e, + 0x87, 0x89, 0x5b, 0xbe, 0x43, 0xdd, 0x66, 0xeb, 0x40, 0xb9, 0xa8, 0xe2, 0x2d, 0x66, 0x47, 0xc0, + 0x79, 0xab, 0x35, 0xb4, 0x48, 0xcf, 0x93, 0xcf, 0xb4, 0x54, 0xbe, 0xc6, 0xc3, 0x14, 0x88, 0x09, + 0x5a, 0x88, 0xe3, 0xa3, 0xe1, 0x04, 0x15, 0xb3, 0x53, 0x41, 0x21, 0xef, 0xc0, 0x08, 0x7f, 0x0f, 0x16, 0x66, 0xb3, 0x67, 0xb3, 0x9a, 0xc9, 0x43, 0x62, 0xe0, 0x44, 0x44, 0x03, 0xa2, 0xc0, 0x14, - 0x44, 0xc6, 0xcf, 0xe5, 0x80, 0xa4, 0x51, 0x8f, 0xd1, 0x7b, 0x1d, 0x6b, 0x98, 0xf4, 0x85, 0x68, + 0x44, 0xc6, 0xcf, 0xe6, 0x80, 0xa4, 0x51, 0x8f, 0xd1, 0x7b, 0x1d, 0x6b, 0x98, 0xf4, 0x85, 0x68, 0x35, 0x16, 0x34, 0x9d, 0x39, 0xab, 0x89, 0x17, 0xf0, 0x8e, 0x17, 0xab, 0x4e, 0x55, 0xc4, 0xf1, - 0x62, 0xe3, 0x47, 0xf2, 0x00, 0x31, 0x36, 0xf9, 0x3c, 0xcf, 0x22, 0xf9, 0x7e, 0xcf, 0x6e, 0x3b, - 0x3b, 0x8e, 0x1e, 0x04, 0x1b, 0x99, 0x7c, 0x5d, 0x96, 0x98, 0x3a, 0x22, 0x79, 0x0f, 0x66, 0x1a, - 0x75, 0x9d, 0x56, 0x71, 0xf9, 0x08, 0xba, 0x56, 0x82, 0x3c, 0x89, 0x8d, 0xe6, 0xf1, 0xea, 0x68, - 0x70, 0xf3, 0x78, 0x3e, 0x10, 0xa2, 0x84, 0x6d, 0x2c, 0x8d, 0xba, 0xf0, 0x6a, 0x69, 0x45, 0xaf, - 0x9a, 0xf8, 0x75, 0x41, 0xd7, 0xea, 0x0a, 0x77, 0x17, 0xb6, 0x4f, 0x68, 0x78, 0x71, 0x47, 0x8e, - 0xf6, 0x09, 0x7b, 0xf1, 0xf3, 0xa8, 0xf6, 0xeb, 0x78, 0x21, 0x15, 0xda, 0x8e, 0xa7, 0xf6, 0xde, - 0x13, 0x1b, 0x13, 0x8c, 0x6a, 0xde, 0xfc, 0x5a, 0xeb, 0x84, 0xc1, 0xcc, 0xb5, 0xf8, 0x92, 0xc2, - 0xcd, 0x0a, 0x32, 0x6c, 0x6c, 0x7e, 0x25, 0x07, 0xa7, 0x32, 0x69, 0xc9, 0x65, 0x80, 0x58, 0xa7, + 0x62, 0xe3, 0x87, 0xf3, 0x00, 0x31, 0x36, 0xf9, 0x3c, 0xcf, 0x22, 0xf9, 0x7e, 0xd7, 0x6e, 0x39, + 0x3b, 0x8e, 0x1e, 0x04, 0x1b, 0x99, 0x7c, 0x5d, 0x96, 0x98, 0x3a, 0x22, 0x79, 0x0f, 0xa6, 0xeb, + 0x35, 0x9d, 0x56, 0x71, 0xf9, 0x08, 0x3a, 0x56, 0x82, 0x3c, 0x89, 0x8d, 0xe6, 0xf1, 0xea, 0x68, + 0x70, 0xf3, 0x78, 0x3e, 0x10, 0xa2, 0x84, 0x6d, 0x2c, 0xf5, 0x9a, 0xf0, 0x6a, 0x69, 0x46, 0xaf, + 0x9a, 0xf8, 0x75, 0x41, 0xc7, 0xea, 0x08, 0x77, 0x17, 0xb6, 0x4f, 0x68, 0x78, 0x71, 0x47, 0x0e, + 0xf7, 0x08, 0x7b, 0xf1, 0x73, 0xa8, 0xf6, 0x6b, 0x7b, 0x21, 0x15, 0xda, 0x8e, 0x67, 0xf6, 0xde, + 0x13, 0x1b, 0x13, 0x0c, 0x6b, 0xde, 0xfc, 0x5a, 0xeb, 0x84, 0xc1, 0xcc, 0x8d, 0xf8, 0x92, 0xc2, + 0xcd, 0x0a, 0x32, 0x6c, 0x6c, 0x7e, 0x39, 0x07, 0xa7, 0x32, 0x69, 0xc9, 0x55, 0x80, 0x58, 0xa7, 0x24, 0x7a, 0x09, 0x77, 0xcc, 0x38, 0x2a, 0x98, 0xa9, 0x60, 0x90, 0x2f, 0x27, 0xb5, 0x41, 0xc7, - 0x1f, 0x84, 0x8b, 0x32, 0x18, 0xa7, 0xae, 0x0d, 0xca, 0xd0, 0x01, 0x19, 0xbf, 0x5a, 0x80, 0x59, - 0x25, 0xe8, 0x18, 0xff, 0xd6, 0x63, 0xdc, 0x15, 0xf6, 0xa1, 0xc4, 0x5a, 0xe3, 0x34, 0x85, 0x3b, - 0x1a, 0x37, 0x7c, 0x79, 0x25, 0xe5, 0x8f, 0x2d, 0xb8, 0x5d, 0x56, 0x91, 0xb9, 0x51, 0x29, 0x6e, - 0x9d, 0xf8, 0x20, 0xd1, 0x4c, 0xbb, 0xa2, 0x69, 0xcc, 0x49, 0x00, 0x53, 0xd5, 0x03, 0xd7, 0xee, - 0x44, 0xb5, 0x71, 0x03, 0x98, 0x4f, 0xf7, 0xad, 0x4d, 0xc3, 0xe6, 0xd5, 0xc5, 0x9e, 0x8b, 0xbc, - 0x2c, 0x23, 0x68, 0x86, 0x46, 0xb5, 0xf8, 0x1e, 0xcc, 0xa6, 0x3e, 0xfa, 0x44, 0xd1, 0x7a, 0x1f, - 0x00, 0x49, 0x7f, 0xc7, 0xf0, 0x26, 0xa2, 0xec, 0xcc, 0xb3, 0xdd, 0x16, 0x37, 0xa7, 0x59, 0x56, - 0x4d, 0x44, 0x7f, 0x3e, 0xaf, 0xfa, 0xc4, 0x3f, 0xed, 0xab, 0xee, 0x0b, 0xda, 0x6d, 0xf8, 0xb9, - 0x7e, 0x63, 0x3a, 0x94, 0xd6, 0xe1, 0xbb, 0x05, 0x38, 0xd3, 0x87, 0x92, 0x1c, 0x24, 0x27, 0x11, - 0xd7, 0x42, 0x5c, 0x1d, 0x5c, 0xe1, 0x93, 0x98, 0x4a, 0xe4, 0xf3, 0x3c, 0x2a, 0x8e, 0x48, 0x39, - 0xcf, 0xef, 0xdf, 0xa8, 0xc6, 0xdf, 0x8f, 0xa0, 0xc9, 0x70, 0x38, 0x1c, 0x4a, 0xde, 0x83, 0x51, - 0x0c, 0x88, 0x90, 0x08, 0x7b, 0xca, 0x30, 0x10, 0xae, 0x04, 0xee, 0x65, 0x3f, 0xb5, 0xc0, 0xbd, - 0x0c, 0x40, 0x3e, 0x07, 0x85, 0xca, 0x83, 0x86, 0x18, 0x97, 0x69, 0x95, 0xfc, 0x41, 0x23, 0x4e, - 0x23, 0x65, 0x6b, 0xf9, 0x9e, 0x18, 0x05, 0x23, 0xbc, 0xb9, 0x5a, 0x17, 0xa3, 0xa2, 0x12, 0xde, - 0x5c, 0xad, 0xc7, 0x84, 0xbb, 0xba, 0xcb, 0xe5, 0xcd, 0xd5, 0xfa, 0x27, 0x37, 0xed, 0xff, 0xd3, - 0x3c, 0x0f, 0xe5, 0xc3, 0x1b, 0xf6, 0x1e, 0x94, 0xb4, 0x58, 0xfd, 0x39, 0xd5, 0xa6, 0x5c, 0x18, - 0xd8, 0x27, 0x2c, 0x86, 0x34, 0x02, 0x99, 0x90, 0x2d, 0xb2, 0x81, 0x57, 0x8d, 0x6d, 0x22, 0x0e, - 0x49, 0x4f, 0x36, 0x9d, 0x84, 0x5c, 0x83, 0xe2, 0x26, 0x75, 0x6d, 0x37, 0x8c, 0x14, 0xa2, 0x68, - 0xa8, 0x1c, 0x22, 0x4c, 0x97, 0x1a, 0x22, 0x44, 0xb4, 0xa9, 0xed, 0x6d, 0x07, 0x4d, 0xdf, 0xc1, - 0x90, 0x5f, 0xd1, 0x59, 0xcc, 0x6d, 0x6a, 0x95, 0x12, 0x9d, 0x41, 0x82, 0xc8, 0xf8, 0xf9, 0x1c, - 0x8c, 0x8b, 0x81, 0xe4, 0x89, 0x34, 0x77, 0xe3, 0xb3, 0x44, 0xf8, 0xae, 0xec, 0x3a, 0x49, 0xdf, - 0x95, 0x5d, 0x1e, 0x57, 0x6b, 0x42, 0x38, 0x8d, 0x46, 0x4f, 0x83, 0x38, 0x1b, 0xa5, 0x3b, 0xb4, - 0x9e, 0x27, 0x31, 0x42, 0x1d, 0xd6, 0x89, 0xd0, 0xf8, 0xdb, 0xe2, 0xcb, 0x6e, 0xae, 0xd6, 0xc9, - 0x32, 0x14, 0xd7, 0x3d, 0x1e, 0x22, 0x4e, 0xcd, 0x0a, 0xdf, 0x16, 0x30, 0xb5, 0x83, 0x24, 0x1e, - 0xfb, 0xbe, 0xba, 0xef, 0x89, 0xbb, 0x8c, 0xf2, 0x7d, 0x5d, 0x0e, 0x4c, 0x7c, 0x5f, 0x84, 0x3a, - 0xf4, 0xf7, 0xd1, 0x8c, 0x4d, 0xe2, 0xfe, 0x35, 0xf4, 0x2f, 0xb8, 0xad, 0x3a, 0x67, 0x8a, 0x22, - 0xb9, 0x53, 0x2c, 0xf6, 0xdb, 0x29, 0xee, 0x5f, 0x33, 0x33, 0xa8, 0xf0, 0x5d, 0x2d, 0x06, 0x37, - 0xa8, 0xff, 0xf0, 0x29, 0xde, 0xa5, 0xb3, 0xdf, 0xd5, 0x92, 0xcd, 0x1b, 0x6a, 0x93, 0xfe, 0xfd, - 0x3c, 0x9c, 0xce, 0x26, 0x54, 0xdb, 0x92, 0x1b, 0xd0, 0x96, 0x8b, 0x50, 0xbc, 0xe5, 0x05, 0xa1, - 0x62, 0x24, 0x88, 0xea, 0xff, 0x3d, 0x01, 0x33, 0xa3, 0x52, 0x76, 0xe7, 0x66, 0x7f, 0x47, 0xcb, - 0x13, 0xf9, 0x61, 0x00, 0x1b, 0x76, 0xe7, 0xe6, 0x45, 0xe4, 0x26, 0x14, 0x4d, 0xe1, 0xe7, 0x97, - 0xe8, 0x1a, 0x09, 0x8e, 0xa4, 0x29, 0xe2, 0x0b, 0x88, 0x96, 0x32, 0x41, 0xc0, 0x48, 0x05, 0xc6, - 0xc5, 0xe8, 0x27, 0x9e, 0x8e, 0x33, 0xa6, 0x8c, 0x9e, 0xc5, 0x44, 0xd2, 0xb1, 0x1d, 0x05, 0x1f, - 0x01, 0x6b, 0x55, 0xe9, 0xb2, 0x87, 0x3b, 0x0a, 0x7f, 0x24, 0xd4, 0xed, 0x31, 0x23, 0x44, 0xe3, - 0x9b, 0x79, 0x00, 0xa9, 0xb5, 0x79, 0x6a, 0x67, 0xd8, 0xe7, 0xb4, 0x19, 0xa6, 0xd8, 0x1b, 0x0d, - 0x9f, 0xad, 0xfe, 0x1e, 0x9a, 0xf3, 0x0c, 0x9f, 0xab, 0x7e, 0x09, 0x46, 0x37, 0x63, 0x85, 0x96, - 0x70, 0x6f, 0x41, 0x75, 0x34, 0x87, 0x1b, 0xdb, 0x30, 0x7f, 0x93, 0x86, 0xb1, 0x7a, 0x4b, 0x3e, - 0x3d, 0x0e, 0x66, 0xfb, 0x2a, 0x4c, 0x08, 0xfc, 0x68, 0xff, 0xe2, 0xba, 0x18, 0x11, 0x13, 0x0a, - 0x75, 0x31, 0x12, 0x81, 0xed, 0x46, 0x55, 0xda, 0xa6, 0x21, 0xfd, 0x64, 0xab, 0x69, 0x00, 0xe1, - 0x4d, 0xc1, 0x96, 0x0d, 0x57, 0xc3, 0xb1, 0xfd, 0x73, 0x1f, 0x4e, 0x45, 0xdf, 0xfe, 0x24, 0xf9, - 0x5e, 0x61, 0x57, 0x4a, 0x91, 0x00, 0x24, 0xe6, 0x38, 0xc0, 0xf6, 0xe4, 0x0f, 0x73, 0xb0, 0x28, - 0x29, 0x1e, 0x38, 0x91, 0xe5, 0xe4, 0x50, 0xc4, 0xe4, 0x6d, 0x98, 0x54, 0x68, 0x84, 0x67, 0x0a, - 0xea, 0xa9, 0x1f, 0x39, 0xe1, 0x9e, 0x15, 0x70, 0xb8, 0xaa, 0xa7, 0x56, 0xd0, 0xc9, 0x36, 0x2c, - 0x36, 0x2a, 0x1b, 0xeb, 0xb1, 0x6f, 0xd9, 0x5d, 0xef, 0x86, 0xd7, 0x6e, 0x7b, 0x8f, 0xb6, 0xcc, - 0x75, 0x99, 0x86, 0x0a, 0x03, 0xdf, 0xa0, 0xd2, 0x5b, 0x71, 0x50, 0x73, 0x3d, 0x6b, 0x07, 0x11, - 0xad, 0x9e, 0xdf, 0x0e, 0xcc, 0x01, 0x5c, 0x8c, 0x7f, 0x9a, 0x83, 0x67, 0x22, 0x47, 0xa7, 0x8c, - 0xf6, 0x25, 0x5a, 0x90, 0x7b, 0x92, 0x2d, 0xc8, 0x3f, 0x91, 0x16, 0xdc, 0x8d, 0xc7, 0xa7, 0xe6, - 0x46, 0x71, 0x09, 0xe4, 0xf7, 0x13, 0x75, 0x7c, 0xc4, 0xa8, 0x3c, 0x9b, 0x8a, 0x74, 0xa0, 0x04, - 0x34, 0x30, 0xde, 0x52, 0x3a, 0x24, 0x83, 0xa1, 0x46, 0x9c, 0x4b, 0x12, 0x7f, 0x33, 0x0f, 0x33, - 0xf7, 0x6a, 0xd5, 0xd5, 0xc8, 0x8e, 0xea, 0xa9, 0xdd, 0x34, 0xb3, 0x2d, 0x95, 0xb4, 0xb6, 0xf5, - 0xdf, 0x39, 0x8d, 0x2d, 0x98, 0x4b, 0x74, 0x03, 0x0a, 0x41, 0xef, 0x72, 0xd7, 0x99, 0x08, 0x2c, - 0x05, 0xa0, 0xd3, 0x59, 0xec, 0xef, 0x5f, 0x33, 0x13, 0xd8, 0xc6, 0xbf, 0x2e, 0x25, 0xf8, 0x8a, - 0xcd, 0xf8, 0x55, 0x98, 0xa8, 0x05, 0x41, 0x8f, 0xfa, 0x5b, 0xe6, 0xba, 0xaa, 0xf4, 0x70, 0x10, - 0xc8, 0xe6, 0x90, 0x19, 0x23, 0x90, 0x4b, 0x50, 0x14, 0x69, 0x10, 0xe4, 0xee, 0x86, 0xfa, 0xe7, - 0x28, 0x8b, 0x82, 0x19, 0x15, 0x93, 0xd7, 0xa1, 0xc4, 0xff, 0xe6, 0x33, 0x5a, 0x74, 0x38, 0xaa, - 0x39, 0x05, 0x3a, 0x5f, 0x01, 0xa6, 0x86, 0x46, 0x5e, 0x81, 0x42, 0x65, 0xd5, 0x14, 0x8a, 0x2d, - 0x21, 0x01, 0xfb, 0x16, 0xd7, 0x3e, 0x6a, 0xd7, 0xa1, 0x55, 0x93, 0xc9, 0xb1, 0x32, 0x24, 0x8c, - 0xd0, 0xc9, 0xe3, 0x0c, 0x90, 0x7a, 0xb3, 0xc4, 0xb1, 0x8c, 0x30, 0x72, 0x05, 0xc6, 0xab, 0xdc, - 0xf8, 0x4f, 0x68, 0xe4, 0x79, 0xf6, 0x58, 0x0e, 0xd2, 0x42, 0x9b, 0x70, 0x10, 0xb9, 0x24, 0x13, - 0x37, 0x16, 0x63, 0x0f, 0x9c, 0x3e, 0xd9, 0x19, 0x5f, 0x85, 0x31, 0x91, 0x2c, 0x60, 0x42, 0xc9, - 0xce, 0x94, 0x4c, 0x12, 0x20, 0x70, 0xd2, 0x9e, 0xe0, 0xf0, 0x24, 0x3d, 0xc1, 0xb7, 0xe1, 0xcc, - 0x4d, 0xd4, 0x43, 0xe9, 0x21, 0xef, 0xb6, 0xcc, 0x9a, 0xd0, 0xec, 0xe3, 0x83, 0x16, 0x57, 0x55, - 0x25, 0xa3, 0xe6, 0x59, 0x3d, 0x5f, 0x4d, 0x86, 0xde, 0x8f, 0x11, 0xf9, 0x00, 0xe6, 0xb3, 0x8a, - 0x84, 0xfe, 0x1f, 0x83, 0xbb, 0x65, 0x57, 0xa0, 0x06, 0x77, 0xcb, 0xe2, 0x40, 0xd6, 0xa1, 0xcc, - 0xe1, 0x95, 0x56, 0xc7, 0x71, 0xf9, 0x1b, 0xc6, 0x54, 0xec, 0x51, 0x2c, 0xb8, 0xda, 0xac, 0x90, - 0xbf, 0x65, 0x68, 0x4e, 0x54, 0x09, 0x4a, 0xf2, 0x53, 0x39, 0x76, 0x2f, 0xe5, 0xa1, 0xf5, 0x71, - 0xfb, 0x9c, 0x16, 0xaf, 0xa1, 0x91, 0x57, 0x53, 0x23, 0xf4, 0x1d, 0x77, 0x57, 0x38, 0x48, 0x6d, - 0x0a, 0x07, 0xa9, 0xb7, 0x3f, 0x92, 0x83, 0x14, 0x67, 0x15, 0x1c, 0x1d, 0x2e, 0x95, 0x7c, 0x51, - 0x27, 0xae, 0x22, 0xed, 0x0b, 0x58, 0xd7, 0xa1, 0x93, 0xfa, 0x96, 0xcb, 0x03, 0x7b, 0xd3, 0x16, - 0x6f, 0xe4, 0x0c, 0x6e, 0xec, 0xd8, 0x75, 0x36, 0xdf, 0xc4, 0x23, 0x84, 0x54, 0x43, 0x33, 0x39, - 0xb0, 0x2b, 0xb4, 0x74, 0xc2, 0xe1, 0x3e, 0xca, 0xe5, 0xf8, 0x0a, 0x2d, 0x3d, 0x76, 0x2c, 0x9c, - 0x46, 0xea, 0xe4, 0xd1, 0x48, 0xc8, 0x15, 0x18, 0xdb, 0xb0, 0x1f, 0x57, 0x76, 0xa9, 0xc8, 0x96, - 0x3c, 0x25, 0xb7, 0x3f, 0x04, 0xae, 0x14, 0xff, 0x80, 0x7b, 0x6d, 0x7c, 0xca, 0x14, 0x68, 0xe4, - 0xaf, 0xe4, 0xe0, 0x34, 0x5f, 0xc6, 0xb2, 0x95, 0x0d, 0x1a, 0x86, 0xac, 0x1f, 0x44, 0x84, 0xd0, - 0xf3, 0xb1, 0xe9, 0x79, 0x36, 0x1e, 0x86, 0xb0, 0x30, 0xc4, 0xce, 0x10, 0x75, 0x5c, 0x20, 0x4a, - 0xb5, 0x50, 0xeb, 0x99, 0xf4, 0x64, 0x13, 0x26, 0x37, 0x6e, 0x54, 0xa2, 0x6a, 0xe7, 0xb4, 0x6c, - 0xb9, 0xda, 0xce, 0xa7, 0xa0, 0x65, 0xf9, 0x4c, 0xa8, 0x6c, 0x50, 0xf4, 0xbf, 0xb3, 0xba, 0x86, - 0x51, 0x23, 0xe6, 0x63, 0x65, 0x42, 0x77, 0xbf, 0x49, 0x93, 0x31, 0xe0, 0x23, 0x44, 0xf2, 0x1e, - 0x77, 0xe3, 0xc4, 0xd8, 0x42, 0xec, 0xaa, 0x7a, 0x2a, 0x0e, 0xe3, 0xca, 0x83, 0xc7, 0x8b, 0x02, - 0x55, 0x0d, 0xa2, 0x12, 0x90, 0x7b, 0x20, 0xa3, 0x50, 0x70, 0xab, 0x70, 0xac, 0xfe, 0x74, 0xec, - 0x3a, 0x25, 0x4d, 0x01, 0xb8, 0x31, 0x79, 0xf2, 0x43, 0xd2, 0xb4, 0x64, 0x0b, 0x16, 0xa8, 0x1b, - 0xfa, 0xb6, 0xe5, 0xb4, 0x44, 0xc0, 0xc7, 0xe8, 0x75, 0x41, 0xe4, 0x48, 0x96, 0x7a, 0xf5, 0x35, - 0x86, 0x56, 0xab, 0xf2, 0xf7, 0x46, 0xb9, 0x6b, 0x9a, 0xa7, 0x90, 0xba, 0xd6, 0xd2, 0xc1, 0xc2, - 0x0b, 0xe4, 0x00, 0x4e, 0x65, 0x52, 0x91, 0x45, 0x28, 0xb6, 0x9c, 0x20, 0x4e, 0xea, 0x54, 0x34, - 0xa3, 0xdf, 0xe4, 0x1c, 0x00, 0x0f, 0x94, 0xa7, 0xd8, 0x6e, 0x4f, 0x20, 0x04, 0x9f, 0x8a, 0x5e, - 0x82, 0xe9, 0x5d, 0xdf, 0xee, 0xee, 0x59, 0xd4, 0x6d, 0x75, 0x3d, 0xc7, 0x15, 0xe7, 0x87, 0x39, - 0x85, 0xd0, 0x35, 0x01, 0x34, 0x3e, 0x27, 0x27, 0x2a, 0x79, 0x4d, 0xf5, 0x9c, 0x2e, 0xe0, 0x28, - 0x8d, 0x77, 0xec, 0xc7, 0x96, 0xbd, 0x4b, 0x35, 0x43, 0x0c, 0xf1, 0x40, 0xf2, 0xb3, 0x39, 0x38, - 0xdb, 0x77, 0x2e, 0x92, 0xeb, 0x70, 0xc6, 0xe6, 0x21, 0x24, 0xac, 0xbd, 0x30, 0xec, 0x06, 0x96, - 0xbc, 0xc5, 0xca, 0x40, 0x5b, 0xa7, 0x44, 0xf1, 0x2d, 0x56, 0x2a, 0x2f, 0xb6, 0x01, 0x79, 0x0f, - 0x9e, 0x75, 0xdc, 0x80, 0x36, 0x7b, 0x3e, 0xb5, 0x24, 0x83, 0xa6, 0xd3, 0xf2, 0x2d, 0xdf, 0x76, - 0x77, 0xa5, 0xe3, 0xb8, 0x79, 0x56, 0xe2, 0x88, 0x30, 0x15, 0xab, 0x4e, 0xcb, 0x37, 0x11, 0xc1, - 0xf8, 0x95, 0x3c, 0x2c, 0xf4, 0x9b, 0xab, 0x64, 0x01, 0xc6, 0xa9, 0xab, 0xf6, 0xa6, 0xfc, 0x49, - 0x9e, 0x81, 0xf8, 0x08, 0x16, 0x7d, 0x59, 0x6c, 0x8a, 0x74, 0x45, 0xe8, 0x3d, 0xa1, 0x1e, 0xb8, - 0xa2, 0x27, 0x4b, 0x4d, 0xf5, 0xd8, 0x3d, 0x07, 0x10, 0x9f, 0xb3, 0x5c, 0xf7, 0x65, 0x4e, 0xd8, - 0x4d, 0x9f, 0x6f, 0x89, 0xe4, 0x34, 0x8c, 0xf1, 0x73, 0x4c, 0xb8, 0xd8, 0x88, 0x5f, 0x4c, 0xa0, - 0x12, 0x9d, 0x8c, 0x07, 0x70, 0x61, 0xa5, 0xa4, 0x75, 0xf6, 0x58, 0x87, 0x0f, 0x4e, 0xe6, 0x7c, - 0x1e, 0xff, 0xe8, 0xf3, 0xd9, 0xf8, 0xcd, 0x12, 0x17, 0x16, 0x2b, 0xbd, 0x70, 0x4f, 0x8a, 0x97, - 0xcb, 0x59, 0x3e, 0x8e, 0xdc, 0xfe, 0x57, 0xf1, 0x25, 0xd0, 0x3d, 0x1b, 0xe5, 0x7b, 0x65, 0x3e, - 0xf3, 0xbd, 0xf2, 0x55, 0x98, 0x58, 0xdd, 0xa3, 0xcd, 0xfd, 0xc8, 0x71, 0xac, 0x28, 0x1e, 0x84, - 0x18, 0x90, 0xa7, 0xb7, 0x88, 0x11, 0xc8, 0x15, 0x00, 0x74, 0xad, 0xe6, 0xb7, 0x28, 0x25, 0x45, - 0x15, 0x7a, 0x62, 0x0b, 0x93, 0x2a, 0x05, 0x05, 0xd9, 0x37, 0xcc, 0x1b, 0xaa, 0x0d, 0x16, 0x67, - 0x1f, 0xf8, 0x3b, 0x02, 0x3d, 0x46, 0x60, 0xcd, 0x53, 0x4e, 0x10, 0x21, 0xef, 0x94, 0x53, 0xc7, - 0x8c, 0x8a, 0x44, 0x3e, 0x07, 0xe3, 0xab, 0xd4, 0x0f, 0x37, 0x37, 0xd7, 0xd1, 0xf0, 0x89, 0x67, - 0x66, 0x2a, 0x62, 0x16, 0x9d, 0x30, 0x6c, 0x7f, 0xef, 0x70, 0x69, 0x2a, 0x74, 0x3a, 0x34, 0xca, - 0x38, 0x61, 0x4a, 0x6c, 0xb2, 0x02, 0x65, 0x6e, 0x9a, 0x11, 0xdf, 0x7f, 0x51, 0xa6, 0x29, 0x72, - 0x09, 0x4b, 0xd8, 0x71, 0x3c, 0xa2, 0xdb, 0x51, 0x0e, 0xa1, 0x14, 0x3e, 0x59, 0x93, 0xa9, 0xb7, - 0xd4, 0xcf, 0x86, 0x78, 0x0f, 0x4d, 0xee, 0xf5, 0xec, 0xeb, 0xd3, 0x14, 0xa4, 0x02, 0x53, 0xab, - 0x5e, 0xa7, 0x6b, 0x87, 0x0e, 0x26, 0x36, 0x3e, 0x10, 0xe2, 0x0b, 0xee, 0xa6, 0x4d, 0xb5, 0x40, - 0x93, 0x85, 0xd4, 0x02, 0x72, 0x03, 0xa6, 0x4d, 0xaf, 0xc7, 0xba, 0x5d, 0x6a, 0x82, 0xb8, 0x84, - 0x82, 0xe6, 0x49, 0x3e, 0x2b, 0x61, 0x02, 0x95, 0x50, 0xfb, 0x68, 0xd1, 0xb9, 0x35, 0x2a, 0x72, - 0x37, 0xe3, 0x49, 0x4e, 0x15, 0x4b, 0xd4, 0x4c, 0x42, 0x29, 0x66, 0x19, 0xaf, 0x79, 0xd7, 0x60, - 0xb2, 0xd1, 0xb8, 0xb7, 0x49, 0x83, 0xf0, 0x46, 0xdb, 0x7b, 0x84, 0x52, 0x49, 0x51, 0x24, 0xbe, - 0x0c, 0x3c, 0x2b, 0x64, 0x2b, 0x62, 0xa7, 0xed, 0x3d, 0x32, 0x55, 0x2c, 0xf2, 0x55, 0xd6, 0x1f, - 0x8a, 0x0c, 0x2f, 0xe2, 0x90, 0x0f, 0xba, 0x66, 0xe0, 0xd9, 0x1f, 0x2f, 0x02, 0x76, 0xd9, 0xd0, - 0x3b, 0x4b, 0x41, 0x47, 0xbf, 0x46, 0xdf, 0x7b, 0x7c, 0x50, 0x69, 0xb5, 0x7c, 0x1a, 0x04, 0x42, - 0x7c, 0xe0, 0x7e, 0x8d, 0xa8, 0xf0, 0xb2, 0x79, 0x81, 0xe6, 0xd7, 0xa8, 0x10, 0x90, 0x55, 0x26, - 0xd7, 0xb2, 0x51, 0x44, 0x83, 0xb9, 0x5a, 0x1d, 0x25, 0x00, 0xa1, 0x49, 0x17, 0x63, 0xce, 0x4d, - 0xeb, 0x9c, 0xae, 0x2e, 0xbe, 0x2a, 0x34, 0xa4, 0x06, 0x33, 0x1c, 0xc0, 0x96, 0x16, 0x4f, 0x7b, - 0x37, 0x17, 0x27, 0xde, 0x11, 0x6c, 0xf0, 0x30, 0xc5, 0xd4, 0x77, 0x6a, 0x70, 0x8a, 0x04, 0x1d, - 0x79, 0x0f, 0xa6, 0x31, 0xa7, 0x48, 0xe4, 0x1c, 0x86, 0x07, 0x79, 0x89, 0xc7, 0xdc, 0x16, 0x25, - 0x09, 0x8f, 0xcb, 0x52, 0x10, 0xec, 0xd5, 0xa5, 0xd7, 0x18, 0x63, 0x80, 0x36, 0x5a, 0x31, 0x83, - 0x53, 0x31, 0x03, 0x51, 0x92, 0x64, 0x10, 0xb6, 0x83, 0x98, 0xc1, 0xcf, 0xe4, 0xe0, 0x2c, 0xab, - 0x48, 0xf5, 0x03, 0xc3, 0x4d, 0x01, 0x0d, 0xd0, 0x78, 0x3e, 0xa4, 0xd7, 0x2e, 0x4b, 0xa1, 0xf2, - 0xb2, 0x82, 0x76, 0xf9, 0xe1, 0xd5, 0xcb, 0x95, 0xf8, 0x67, 0x43, 0x12, 0xf1, 0x28, 0xc4, 0x7d, - 0x79, 0xaa, 0xc2, 0x7b, 0x10, 0xec, 0x65, 0x71, 0xc0, 0x8f, 0x62, 0x1f, 0x9f, 0xfd, 0x51, 0x67, - 0x3e, 0xf2, 0x47, 0xf5, 0xe5, 0xa9, 0x7e, 0x54, 0xd8, 0x0e, 0x32, 0x3f, 0xea, 0x3a, 0x4c, 0xa1, - 0x68, 0x25, 0x44, 0x5a, 0x5f, 0x64, 0x5b, 0xc2, 0x35, 0xa1, 0x15, 0x98, 0x25, 0xf6, 0xf3, 0xbe, - 0xf8, 0x75, 0x7b, 0xa4, 0x38, 0x5e, 0x2e, 0xde, 0x1e, 0x29, 0xce, 0x96, 0x89, 0x39, 0x11, 0x75, - 0xbc, 0x79, 0x2a, 0xf3, 0x43, 0x50, 0xd5, 0xd0, 0xa8, 0x6c, 0xac, 0xc7, 0xf7, 0xe5, 0xef, 0x2f, - 0xa7, 0x28, 0xad, 0x6d, 0x03, 0x9c, 0xa2, 0xb6, 0xb8, 0x8f, 0xbe, 0xd2, 0x0d, 0x52, 0xd5, 0xa0, - 0x81, 0x93, 0xaa, 0x86, 0x04, 0x8d, 0x99, 0xc0, 0x36, 0x7e, 0x77, 0x32, 0xc1, 0x57, 0x18, 0x42, - 0x1b, 0x30, 0xc6, 0x35, 0x09, 0xa2, 0x93, 0xd1, 0x22, 0x86, 0xeb, 0x19, 0x4c, 0x51, 0x42, 0xce, - 0x42, 0xa1, 0xd1, 0xb8, 0x27, 0x3a, 0x19, 0xcd, 0xa1, 0x83, 0xc0, 0x33, 0x19, 0x8c, 0x8d, 0x10, - 0xda, 0x38, 0x2b, 0x99, 0x60, 0xd8, 0x49, 0x66, 0x22, 0x94, 0xf5, 0xb7, 0xbc, 0xd7, 0x8f, 0xc4, - 0xfd, 0x2d, 0xee, 0xf5, 0xf1, 0x6d, 0x7e, 0x15, 0x16, 0x2a, 0x41, 0x40, 0x7d, 0x36, 0x23, 0x84, - 0xe9, 0xac, 0x2f, 0xee, 0x9e, 0xe2, 0x08, 0xc6, 0x4a, 0xed, 0x66, 0x60, 0xf6, 0x45, 0x24, 0x17, - 0xa1, 0x58, 0xe9, 0xb5, 0x1c, 0xea, 0x36, 0xb5, 0x98, 0x93, 0xb6, 0x80, 0x99, 0x51, 0x29, 0x79, - 0x1f, 0x4e, 0x25, 0x62, 0xd7, 0x8a, 0x1e, 0x18, 0x8f, 0x77, 0x55, 0x79, 0x37, 0x8e, 0xcd, 0x7d, - 0x78, 0x97, 0x64, 0x53, 0x92, 0x0a, 0x94, 0xd7, 0xd0, 0x09, 0xb0, 0x4a, 0xf9, 0xcb, 0xa3, 0xe7, - 0x73, 0xef, 0x4f, 0xae, 0xc9, 0x10, 0xd1, 0x7d, 0x5b, 0x51, 0xa1, 0x99, 0x42, 0x27, 0x77, 0x60, - 0x2e, 0x09, 0x63, 0x67, 0x33, 0x57, 0x5a, 0xe0, 0xae, 0x96, 0xe2, 0x82, 0xa7, 0x73, 0x16, 0x15, - 0xd9, 0x86, 0xd9, 0xd8, 0xdc, 0x4d, 0x57, 0x65, 0x48, 0x2b, 0xfa, 0xa8, 0x5c, 0xaa, 0x33, 0x9e, - 0x11, 0x93, 0x71, 0x2e, 0x36, 0x9d, 0x8b, 0x54, 0x1a, 0x66, 0x9a, 0x1d, 0x69, 0xc1, 0x74, 0xc3, - 0xd9, 0x75, 0x1d, 0x77, 0xf7, 0x0e, 0x3d, 0xa8, 0xdb, 0x8e, 0x2f, 0xec, 0x99, 0xa5, 0xb7, 0x42, - 0x25, 0x38, 0xe8, 0x74, 0x68, 0xe8, 0xe3, 0xaa, 0x67, 0xe5, 0x18, 0xe1, 0x80, 0x5d, 0x51, 0x17, - 0x03, 0x4e, 0x87, 0x4e, 0xc1, 0x5d, 0xdb, 0xd1, 0x8e, 0x77, 0x9d, 0xa7, 0xa6, 0x4e, 0x2a, 0x0d, - 0xa9, 0x4e, 0x6a, 0xc3, 0xec, 0x9a, 0xdb, 0xf4, 0x0f, 0xf0, 0x01, 0x58, 0x7e, 0xdc, 0xd4, 0x31, - 0x1f, 0xf7, 0xa2, 0xf8, 0xb8, 0x67, 0x6d, 0x39, 0xc3, 0xb2, 0x3e, 0x2f, 0xcd, 0x98, 0x34, 0x60, - 0x16, 0xef, 0x0c, 0xb5, 0x6a, 0xbd, 0xe6, 0x3a, 0xa1, 0x63, 0x87, 0xb4, 0x25, 0xc4, 0x86, 0x28, - 0x7f, 0x16, 0x57, 0x1b, 0x38, 0xad, 0xae, 0xe5, 0x48, 0x14, 0x95, 0x69, 0x8a, 0x7e, 0xd0, 0xdd, - 0x7d, 0xe6, 0xcf, 0xe8, 0xee, 0x5e, 0x83, 0x99, 0x64, 0xa0, 0x90, 0x72, 0x7c, 0xda, 0x07, 0x58, - 0xc4, 0x84, 0x06, 0xaf, 0x87, 0x62, 0xa2, 0x16, 0x8a, 0x2a, 0x11, 0x22, 0x24, 0xa1, 0x06, 0x98, - 0xd5, 0xd4, 0x00, 0xda, 0xae, 0x74, 0x12, 0x35, 0x40, 0x1d, 0xe0, 0x86, 0xe7, 0x37, 0x69, 0x05, - 0xbd, 0xef, 0x89, 0x96, 0x65, 0x90, 0x31, 0x8d, 0x0b, 0xf9, 0xfa, 0xd9, 0x61, 0xbf, 0xad, 0x64, - 0x10, 0x05, 0x85, 0x07, 0xb1, 0xe1, 0x4c, 0xdd, 0xa7, 0x3b, 0xd4, 0xf7, 0x69, 0x4b, 0xdc, 0x60, - 0x56, 0x1c, 0xb7, 0x25, 0x53, 0x47, 0x8a, 0x3c, 0x03, 0x5d, 0x89, 0x12, 0x59, 0xff, 0x6f, 0x73, - 0x24, 0xf5, 0x30, 0xed, 0xc3, 0x27, 0xa5, 0x86, 0x98, 0x3f, 0xa1, 0x1a, 0xc2, 0xf8, 0xf1, 0x3c, - 0x2c, 0xf4, 0xeb, 0xb2, 0x01, 0xb7, 0xd1, 0x4f, 0x43, 0x7a, 0x17, 0x12, 0xb7, 0xd2, 0x32, 0x4d, - 0xee, 0x45, 0xcb, 0x90, 0xbd, 0xd9, 0x88, 0x5b, 0xea, 0x5c, 0x92, 0x60, 0xcb, 0x6f, 0x93, 0xeb, - 0x30, 0xa9, 0x74, 0x30, 0xee, 0xf7, 0xfd, 0x86, 0xc3, 0x84, 0x9d, 0xb8, 0xcf, 0x4f, 0x83, 0x38, - 0x6e, 0xe4, 0x2d, 0x96, 0xff, 0x22, 0x65, 0x1e, 0x24, 0x61, 0x8c, 0xdb, 0xc1, 0x04, 0x81, 0x47, - 0x08, 0xe0, 0xd9, 0xc2, 0xb7, 0x69, 0x13, 0xff, 0x36, 0x7e, 0xa9, 0xc4, 0xa5, 0x06, 0xf5, 0xce, - 0xd9, 0xcf, 0x42, 0x3e, 0x71, 0x17, 0xcd, 0x9f, 0xe4, 0x2e, 0x5a, 0x38, 0xfe, 0x2e, 0x3a, 0x72, - 0xdc, 0x5d, 0x34, 0x71, 0x59, 0x1c, 0x3d, 0xe1, 0x65, 0x71, 0xfc, 0x44, 0x97, 0x45, 0xed, 0x1e, - 0x5b, 0x3c, 0xee, 0x1e, 0xfb, 0x17, 0x57, 0xcb, 0xa7, 0xf5, 0x6a, 0x99, 0x25, 0x56, 0x9e, 0xe8, - 0x6a, 0x99, 0xba, 0x19, 0xce, 0x3e, 0x99, 0x9b, 0x21, 0x79, 0x62, 0x37, 0xc3, 0xb9, 0x8f, 0x7b, - 0x33, 0x9c, 0x7f, 0x92, 0x37, 0xc3, 0x53, 0x7f, 0x1e, 0x6f, 0x86, 0xa7, 0xff, 0xe3, 0xdc, 0x0c, - 0xaf, 0x41, 0xb1, 0xee, 0x05, 0xe1, 0x0d, 0xcf, 0xef, 0xe0, 0xe5, 0xb4, 0x24, 0x14, 0xf1, 0x5e, - 0xc0, 0xd3, 0xbf, 0x6b, 0xd2, 0x99, 0x40, 0x24, 0x2b, 0x72, 0xc2, 0xc9, 0xab, 0xd8, 0x42, 0xfc, - 0x16, 0x22, 0x66, 0x8a, 0xb8, 0x91, 0xa5, 0xe7, 0x9b, 0x20, 0xb9, 0x3d, 0x52, 0x1c, 0x2b, 0x8f, - 0xdf, 0x1e, 0x29, 0x96, 0xcb, 0xb3, 0x43, 0x5c, 0x2d, 0xff, 0x12, 0x94, 0x93, 0xd2, 0xee, 0xf1, - 0x31, 0xe6, 0x9f, 0x58, 0xb4, 0x56, 0x26, 0x8b, 0x27, 0xa5, 0x4d, 0x72, 0x05, 0xa0, 0xee, 0x3b, - 0x0f, 0xed, 0x90, 0xde, 0x91, 0xc6, 0x9e, 0x22, 0xa9, 0x02, 0x87, 0xb2, 0x09, 0x6a, 0x2a, 0x28, - 0xd1, 0x45, 0x2b, 0x9f, 0x75, 0xd1, 0x32, 0x7e, 0x2c, 0x0f, 0xb3, 0x3c, 0x4c, 0xe1, 0xd3, 0xff, - 0x52, 0xff, 0xae, 0x76, 0x7d, 0x7e, 0x36, 0x4e, 0x15, 0xa3, 0xb6, 0x6e, 0xc0, 0x5b, 0xfd, 0x57, - 0xe0, 0x54, 0xaa, 0x2b, 0xf0, 0x0a, 0x5d, 0x95, 0x01, 0x22, 0x53, 0x97, 0xe8, 0x85, 0xec, 0x4a, - 0xee, 0x5f, 0x33, 0x53, 0x14, 0xc6, 0xaf, 0x8f, 0xa6, 0xf8, 0x8b, 0x57, 0x7b, 0xf5, 0x1d, 0x3e, - 0x77, 0xb2, 0x77, 0xf8, 0xfc, 0x70, 0xef, 0xf0, 0x09, 0x09, 0xa2, 0x30, 0x8c, 0x04, 0xf1, 0x3e, - 0x4c, 0x6d, 0x52, 0xbb, 0x13, 0x6c, 0x7a, 0x22, 0xef, 0x20, 0x77, 0x2d, 0x92, 0xf1, 0x1f, 0x59, - 0x99, 0xbc, 0x01, 0x46, 0x26, 0xd2, 0x21, 0x23, 0x60, 0x67, 0x24, 0x4f, 0x44, 0x68, 0xea, 0x1c, - 0xd4, 0x6b, 0xfd, 0xe8, 0x80, 0x6b, 0x7d, 0x03, 0x4a, 0x82, 0x2e, 0x0e, 0xac, 0x1f, 0xdf, 0x3f, - 0x59, 0x11, 0xc2, 0x65, 0xed, 0xd2, 0xc7, 0x77, 0x3a, 0xaa, 0x9d, 0x5f, 0x3d, 0x35, 0x26, 0xac, - 0x0b, 0xe4, 0x43, 0x13, 0xeb, 0x82, 0xf1, 0xb8, 0x0b, 0xe4, 0xa3, 0x14, 0xef, 0x02, 0x05, 0x89, - 0xbc, 0x0d, 0xd3, 0x95, 0x7a, 0x4d, 0x25, 0x2b, 0xc6, 0xa6, 0x00, 0x76, 0xd7, 0xb1, 0x34, 0xd2, - 0x04, 0xee, 0xa0, 0xab, 0xd8, 0xc4, 0x9f, 0xd1, 0x55, 0x2c, 0x79, 0x69, 0x80, 0x93, 0x5e, 0x1a, - 0x7e, 0xab, 0x24, 0xf7, 0x87, 0x4f, 0xf6, 0x71, 0x46, 0x7f, 0x6e, 0x29, 0x9c, 0xf0, 0xb9, 0x65, - 0xe4, 0x38, 0x31, 0x55, 0x91, 0x86, 0xc7, 0x3e, 0xf6, 0xd3, 0xc9, 0xf8, 0x09, 0xe5, 0xdb, 0xc4, - 0xe2, 0x2b, 0x0e, 0xb3, 0xf8, 0x32, 0x65, 0xe2, 0x89, 0x8f, 0x2f, 0x13, 0xc3, 0x89, 0x65, 0xe2, - 0x46, 0xec, 0xbb, 0x3f, 0x79, 0xac, 0x4b, 0xd4, 0x39, 0xa1, 0xb7, 0x98, 0xcd, 0x8e, 0x42, 0x19, - 0x79, 0xf1, 0x7f, 0x5f, 0x09, 0xda, 0x5f, 0xcb, 0x16, 0xb4, 0x07, 0x1f, 0x40, 0x7f, 0x21, 0x6a, - 0xff, 0x85, 0xa8, 0xfd, 0x67, 0x22, 0x6a, 0xdf, 0x03, 0x62, 0xf7, 0xc2, 0x3d, 0xea, 0x86, 0x4e, - 0x13, 0x23, 0x21, 0xb3, 0x21, 0x46, 0xa1, 0x5b, 0xac, 0x91, 0x74, 0xa9, 0xba, 0x46, 0xb4, 0x52, - 0x36, 0x03, 0x78, 0xf4, 0xd8, 0xa1, 0x45, 0x68, 0x1f, 0x57, 0xd4, 0x03, 0xdb, 0x77, 0xf1, 0x40, - 0xba, 0x02, 0xe3, 0x32, 0xf2, 0x6e, 0x2e, 0x56, 0x73, 0xa7, 0x43, 0xee, 0x4a, 0x2c, 0xb2, 0x0c, - 0x45, 0x49, 0xac, 0xa6, 0x2f, 0x7b, 0x24, 0x60, 0x5a, 0x50, 0x53, 0x01, 0x33, 0xfe, 0xf3, 0x11, - 0xb9, 0x6b, 0xb3, 0x0f, 0xae, 0xdb, 0xbe, 0xdd, 0xc1, 0xec, 0xa9, 0xd1, 0xa2, 0x52, 0x04, 0xf8, - 0xc4, 0x3a, 0x4c, 0x78, 0xb3, 0xe8, 0x24, 0x1f, 0x29, 0x74, 0x72, 0x9c, 0xa0, 0xbe, 0x30, 0x44, - 0x82, 0xfa, 0x37, 0xb4, 0xec, 0xee, 0x23, 0x71, 0x3a, 0x61, 0xb6, 0x93, 0x0d, 0xce, 0xeb, 0x7e, - 0x5d, 0x4d, 0xc3, 0x3e, 0x1a, 0x07, 0xb2, 0x43, 0xca, 0x01, 0x09, 0xd8, 0xa3, 0x1b, 0xc9, 0xd8, - 0x49, 0x82, 0x92, 0x8f, 0xff, 0x47, 0x0d, 0x4a, 0xbe, 0x06, 0x20, 0x4e, 0xd7, 0xd8, 0x1a, 0xe2, - 0x25, 0xdc, 0x7c, 0x84, 0x65, 0x7e, 0x18, 0xb6, 0xfb, 0x24, 0x4d, 0x52, 0x08, 0x8d, 0x7f, 0x41, - 0x60, 0xb6, 0xd1, 0xb8, 0x57, 0x75, 0xec, 0x5d, 0xd7, 0x0b, 0x42, 0xa7, 0x59, 0x73, 0x77, 0x3c, - 0x26, 0x8e, 0x47, 0x27, 0x80, 0x12, 0x4e, 0x3a, 0xde, 0xfd, 0xa3, 0x62, 0x76, 0xdd, 0x5b, 0xf3, - 0x7d, 0xa9, 0x10, 0xe5, 0xd7, 0x3d, 0xca, 0x00, 0x26, 0x87, 0x33, 0x89, 0xb7, 0xd1, 0xc3, 0x60, - 0x2e, 0xc2, 0xe4, 0x04, 0x25, 0xde, 0x80, 0x83, 0x4c, 0x59, 0x46, 0x68, 0x7a, 0xc2, 0x8a, 0x1b, - 0xd0, 0x19, 0x2d, 0xb4, 0x79, 0x5c, 0xcc, 0xd7, 0xae, 0x90, 0x3f, 0x70, 0xd7, 0xee, 0x22, 0x5c, - 0x35, 0x9d, 0x4c, 0xad, 0x81, 0x03, 0x38, 0xa5, 0xb9, 0xf9, 0x0f, 0xfb, 0xc2, 0xf3, 0x8a, 0x90, - 0xb0, 0x0d, 0x34, 0x4f, 0xcf, 0x78, 0xe6, 0x51, 0xd3, 0xa1, 0x66, 0xd6, 0x40, 0x7e, 0x2c, 0x07, - 0xe7, 0x32, 0x4b, 0xa2, 0xd5, 0x3d, 0xa9, 0x85, 0x97, 0x57, 0x36, 0x0d, 0x9e, 0xf8, 0xb5, 0x5f, - 0xd5, 0x56, 0xc6, 0x56, 0x30, 0xb8, 0x26, 0xf2, 0x9b, 0x39, 0x38, 0xa3, 0x61, 0x44, 0xbb, 0x65, - 0x10, 0x45, 0xc0, 0xc9, 0x9c, 0xd7, 0x1f, 0x3e, 0x99, 0x79, 0xfd, 0x82, 0xde, 0x96, 0x78, 0xb7, - 0x54, 0xdb, 0xd0, 0xef, 0x0b, 0xc9, 0x43, 0x98, 0xc5, 0x22, 0xf9, 0xda, 0xc4, 0xe6, 0xac, 0x78, - 0xa4, 0x9a, 0x8f, 0x3f, 0x9b, 0x87, 0xae, 0x60, 0xb2, 0xf5, 0xca, 0xf2, 0x77, 0x0f, 0x97, 0xa6, - 0x34, 0x74, 0x19, 0xb0, 0xdd, 0x8a, 0x9f, 0xac, 0x1c, 0x77, 0xc7, 0x53, 0xf7, 0xfd, 0x54, 0x15, - 0xe4, 0x9f, 0xe6, 0xf8, 0xfb, 0x01, 0x6f, 0xc6, 0x0d, 0xdf, 0xeb, 0x44, 0xe5, 0xd2, 0x06, 0xb7, - 0x4f, 0xb7, 0xb5, 0x9f, 0x4c, 0xb7, 0xbd, 0x84, 0x9f, 0xcc, 0xf7, 0x04, 0x6b, 0xc7, 0xf7, 0x3a, - 0xf1, 0xe7, 0xab, 0x1d, 0xd7, 0xf7, 0x23, 0xc9, 0x0f, 0xe7, 0xe0, 0xac, 0xa6, 0xf6, 0x54, 0x33, - 0xf1, 0x88, 0x00, 0x21, 0x73, 0x51, 0xe8, 0xa0, 0xb8, 0x68, 0xe5, 0xb2, 0x98, 0xff, 0x17, 0xf0, - 0x0b, 0x94, 0x48, 0xb5, 0x0c, 0xc9, 0xea, 0x70, 0x2c, 0xe5, 0x13, 0xfa, 0xd7, 0x42, 0x1c, 0x98, - 0x45, 0xa3, 0x1e, 0xcd, 0x56, 0x7c, 0xbe, 0xbf, 0xad, 0x78, 0x94, 0x96, 0x0d, 0x73, 0x66, 0xf4, - 0x37, 0x18, 0x4f, 0x73, 0x25, 0x3f, 0x04, 0x67, 0x53, 0xc0, 0x68, 0xb5, 0x9d, 0xea, 0xbb, 0xda, - 0x3e, 0x7d, 0x74, 0xb8, 0xf4, 0x72, 0x56, 0x6d, 0x59, 0x2b, 0xad, 0x7f, 0x0d, 0xc4, 0x06, 0x88, - 0x0b, 0x85, 0xf4, 0x93, 0x3d, 0x41, 0x3f, 0x2d, 0xe6, 0x87, 0x82, 0xcf, 0xf6, 0x72, 0xe5, 0x1b, - 0xd4, 0x23, 0x2f, 0x46, 0x22, 0x14, 0x4a, 0x4a, 0xbe, 0x90, 0x03, 0x61, 0xe7, 0xd2, 0xa7, 0x92, - 0xef, 0x1e, 0x2e, 0x69, 0xd8, 0xec, 0x0e, 0xa4, 0x26, 0x22, 0xd1, 0x84, 0x4d, 0x15, 0x91, 0xfc, - 0x46, 0x0e, 0xe6, 0x19, 0x20, 0x9e, 0x54, 0xa2, 0x51, 0x0b, 0x83, 0x66, 0xfd, 0xde, 0x93, 0x99, - 0xf5, 0xcf, 0xe3, 0x37, 0xaa, 0xb3, 0x3e, 0xd5, 0x25, 0x99, 0x1f, 0x87, 0xb3, 0x5d, 0xb3, 0x1f, - 0xd3, 0x66, 0xfb, 0xd9, 0x21, 0x66, 0x3b, 0x1f, 0x80, 0xe3, 0x67, 0x7b, 0xdf, 0x5a, 0xc8, 0x26, - 0x94, 0xc4, 0xf5, 0x87, 0x77, 0xd8, 0x73, 0x5a, 0xe4, 0x72, 0xb5, 0x88, 0xdf, 0x49, 0x45, 0x3a, - 0x95, 0x54, 0x0b, 0x35, 0x2e, 0xc4, 0x85, 0x39, 0xfe, 0x5b, 0xd7, 0x4f, 0x2d, 0xf5, 0xd5, 0x4f, - 0x5d, 0x14, 0x2d, 0x3a, 0x2f, 0xf8, 0x27, 0xd4, 0x54, 0x6a, 0xc4, 0xb1, 0x0c, 0xc6, 0xa4, 0x0b, - 0x44, 0x03, 0xf3, 0x45, 0x7b, 0x7e, 0xb0, 0x56, 0xea, 0x65, 0x51, 0xe7, 0x52, 0xb2, 0xce, 0xe4, - 0xca, 0xcd, 0xe0, 0x4d, 0x6c, 0x98, 0x11, 0x50, 0x6f, 0x9f, 0xf2, 0x1d, 0xfe, 0x79, 0x2d, 0xe6, - 0x5b, 0xa2, 0x94, 0xdf, 0xe1, 0x64, 0x4d, 0x18, 0x93, 0x2f, 0xb1, 0xa1, 0x27, 0xf9, 0x91, 0x7b, - 0x30, 0x5b, 0xe9, 0x76, 0xdb, 0x0e, 0x6d, 0x61, 0x2b, 0xcd, 0x1e, 0x6b, 0x93, 0x11, 0x27, 0xc4, - 0xb4, 0x79, 0xa1, 0xb8, 0x58, 0xfa, 0xbd, 0xc4, 0x76, 0x93, 0xa2, 0x35, 0x7e, 0x34, 0x97, 0xfa, - 0x68, 0xf2, 0x2a, 0x4c, 0xe0, 0x0f, 0x25, 0x8c, 0x10, 0x6a, 0x69, 0xf8, 0x27, 0xa2, 0xfe, 0x27, - 0x46, 0x60, 0xc2, 0x92, 0x1a, 0x4a, 0xb4, 0xc0, 0x85, 0x25, 0xa1, 0x4a, 0x88, 0x95, 0x07, 0x4b, - 0xd2, 0x87, 0xa7, 0x10, 0x0b, 0x5d, 0xe8, 0xc3, 0x23, 0x3c, 0x77, 0x8c, 0xff, 0x2a, 0xaf, 0x4f, - 0x3b, 0x72, 0x51, 0x91, 0xdb, 0x95, 0x60, 0xa6, 0x52, 0x6e, 0x57, 0xa4, 0xf5, 0x5f, 0xc9, 0xc1, - 0xdc, 0x3d, 0x25, 0x4d, 0xf3, 0xa6, 0x87, 0xe3, 0x32, 0x38, 0x21, 0xf1, 0x93, 0xca, 0x91, 0xaa, - 0xe6, 0x87, 0x66, 0x33, 0x05, 0xa7, 0x8c, 0x99, 0xf5, 0x3d, 0xe8, 0xdf, 0x89, 0x1f, 0xa6, 0xa4, - 0xaa, 0xe5, 0xe8, 0x1c, 0x7e, 0xc2, 0xe4, 0x2a, 0xc6, 0x4f, 0xe4, 0x61, 0x52, 0x59, 0x31, 0xe4, - 0xb3, 0x50, 0x52, 0xab, 0x55, 0x55, 0x7c, 0xea, 0x57, 0x9a, 0x1a, 0x16, 0xea, 0xf8, 0xa8, 0xdd, - 0xd1, 0x74, 0x7c, 0x6c, 0x5d, 0x20, 0xf4, 0x84, 0x37, 0xa1, 0xf7, 0x32, 0x6e, 0x42, 0x38, 0xcb, - 0x15, 0x9d, 0xce, 0xc0, 0xfb, 0xd0, 0xdb, 0xe9, 0xfb, 0x10, 0xaa, 0x97, 0x14, 0xfa, 0xfe, 0xb7, - 0x22, 0xe3, 0xa7, 0x73, 0x50, 0x4e, 0xae, 0xe9, 0x4f, 0xa4, 0x57, 0x4e, 0xf0, 0x20, 0xf4, 0xad, - 0x7c, 0x94, 0x5b, 0x48, 0x3a, 0xb9, 0x3f, 0xad, 0xa6, 0x8e, 0xef, 0x68, 0x6f, 0x35, 0xcf, 0xe8, - 0xf1, 0x1a, 0xd5, 0xf0, 0x30, 0xd9, 0x41, 0x5a, 0x47, 0xbe, 0xfd, 0x8b, 0x4b, 0x9f, 0x32, 0xbe, - 0x08, 0xf3, 0xc9, 0xee, 0xc0, 0xf7, 0x9a, 0x0a, 0xcc, 0xe8, 0xf0, 0x64, 0x66, 0xb2, 0x24, 0x95, - 0x99, 0xc4, 0x37, 0xfe, 0x20, 0x9f, 0xe4, 0x2d, 0xcc, 0x1e, 0xd9, 0x1e, 0xa5, 0x1a, 0xca, 0x88, - 0x3d, 0x8a, 0x83, 0x4c, 0x59, 0x76, 0x92, 0xec, 0x82, 0x91, 0xab, 0x76, 0x21, 0xdb, 0x55, 0x9b, - 0x5c, 0x4f, 0xd8, 0x70, 0x2b, 0x71, 0xc5, 0x1e, 0xd1, 0x6d, 0x2b, 0xb6, 0xe3, 0x4e, 0x99, 0x6e, - 0xcf, 0x6b, 0x41, 0xf2, 0x25, 0xfd, 0x68, 0xac, 0x5d, 0x0f, 0xb1, 0x80, 0x13, 0x67, 0x22, 0x93, - 0x5b, 0x30, 0xce, 0x3e, 0x73, 0xc3, 0xee, 0x8a, 0x67, 0x18, 0x12, 0x05, 0x6e, 0x68, 0x47, 0xf7, - 0x43, 0x25, 0x76, 0x43, 0x9b, 0x32, 0x09, 0x41, 0x9d, 0x58, 0x02, 0xd1, 0xf8, 0xbf, 0x72, 0x6c, - 0xfd, 0x37, 0xf7, 0xbf, 0xcf, 0xd2, 0x0a, 0xb2, 0x26, 0x0d, 0xb0, 0xca, 0xfd, 0x37, 0x79, 0x9e, - 0x2d, 0x4a, 0x4c, 0x9f, 0x37, 0x60, 0x6c, 0xd3, 0xf6, 0x77, 0x69, 0x28, 0xf2, 0x28, 0xa9, 0x5c, - 0x78, 0x41, 0x1c, 0xf5, 0x2c, 0xc4, 0xdf, 0xa6, 0x20, 0x50, 0x55, 0x67, 0xf9, 0xa1, 0x54, 0x67, - 0x8a, 0xe6, 0xbe, 0xf0, 0xc4, 0x34, 0xf7, 0x3f, 0x10, 0x25, 0x86, 0xaa, 0x84, 0x43, 0xc4, 0x60, - 0x3f, 0x9f, 0xcc, 0xc3, 0x96, 0x8a, 0x96, 0x1f, 0xb3, 0x23, 0xd7, 0xd5, 0xcc, 0x6e, 0x8a, 0xcf, - 0xf0, 0x31, 0x39, 0xdc, 0x8c, 0xef, 0x8c, 0xf0, 0x3e, 0x16, 0x1d, 0x75, 0x41, 0x8b, 0x8c, 0x80, - 0xeb, 0x24, 0xa1, 0xd5, 0xe4, 0x31, 0x12, 0x2e, 0xc0, 0x08, 0x9b, 0x9b, 0xa2, 0x37, 0x11, 0x8f, - 0xcd, 0x5f, 0x15, 0x8f, 0x95, 0xb3, 0xb5, 0x8c, 0x67, 0x92, 0x9a, 0xfe, 0x13, 0x8f, 0x2d, 0x75, - 0x2d, 0x23, 0x06, 0x6b, 0x41, 0x94, 0xf7, 0x44, 0x6d, 0x41, 0x67, 0xc7, 0x4e, 0x27, 0x58, 0x54, - 0x92, 0x2d, 0xad, 0xc1, 0xf4, 0x03, 0xc7, 0x6d, 0x79, 0x8f, 0x82, 0x2a, 0x0d, 0xf6, 0x43, 0xaf, - 0x2b, 0x2c, 0x91, 0x51, 0xc3, 0xff, 0x88, 0x97, 0x58, 0x2d, 0x5e, 0xa4, 0x3e, 0x87, 0xe8, 0x44, - 0x64, 0x05, 0xa6, 0xb4, 0xc8, 0xc1, 0xe2, 0x95, 0x13, 0x75, 0x9c, 0x7a, 0xdc, 0x61, 0x55, 0xc7, - 0xa9, 0x91, 0xb0, 0x53, 0x5a, 0x7c, 0xbf, 0xf2, 0xd6, 0x99, 0xfa, 0x76, 0x81, 0x43, 0xae, 0x41, - 0x91, 0x87, 0x97, 0xa9, 0x55, 0xd5, 0xe7, 0xa9, 0x00, 0x61, 0x89, 0xf0, 0x4c, 0x12, 0x91, 0xac, - 0xc2, 0xd4, 0x8a, 0x17, 0xd6, 0xdc, 0x20, 0xb4, 0xdd, 0x26, 0x8d, 0xe2, 0x24, 0x63, 0x63, 0xb7, - 0xbd, 0xd0, 0x72, 0x44, 0x89, 0x4e, 0xaf, 0xd3, 0xb0, 0xae, 0xbe, 0xed, 0x39, 0x2e, 0xdf, 0x3a, - 0x27, 0xe3, 0xae, 0xfe, 0xd0, 0x73, 0xdc, 0x54, 0x68, 0xe2, 0x18, 0x35, 0x8e, 0x65, 0xc2, 0xfd, - 0x1d, 0xcd, 0x91, 0xbb, 0x5e, 0x8b, 0x1a, 0x9f, 0x81, 0xb2, 0xd8, 0xf1, 0xa2, 0x6c, 0xb2, 0x68, - 0x39, 0x51, 0xab, 0x9a, 0xea, 0x2e, 0xd5, 0x74, 0x5a, 0xbe, 0x89, 0x50, 0xf4, 0x39, 0xbc, 0x4b, - 0xc3, 0x47, 0x9e, 0xbf, 0x6f, 0xd2, 0x20, 0xf4, 0x1d, 0x9e, 0x9c, 0x16, 0xd7, 0xf9, 0x67, 0xc9, - 0xdb, 0x30, 0x8a, 0xb6, 0xb9, 0x89, 0x83, 0x27, 0x59, 0xc7, 0xca, 0x94, 0x58, 0x1f, 0xa3, 0x68, - 0xe8, 0x6b, 0x72, 0x22, 0xf2, 0x06, 0x8c, 0x54, 0xa9, 0x7b, 0x90, 0xc8, 0x75, 0x99, 0x22, 0x8e, - 0xf6, 0x9b, 0x16, 0x75, 0x0f, 0x4c, 0x24, 0x31, 0x7e, 0x3a, 0x0f, 0xa7, 0x32, 0x3e, 0xeb, 0xfe, - 0x67, 0x9f, 0xd2, 0x4d, 0x77, 0x45, 0xdb, 0x74, 0xe5, 0x8b, 0x79, 0xdf, 0x8e, 0xcf, 0xdc, 0x83, - 0xff, 0x56, 0x0e, 0xce, 0xe8, 0x2b, 0x45, 0x18, 0xe3, 0xdf, 0xbf, 0x46, 0xde, 0x82, 0xb1, 0x5b, - 0xd4, 0x6e, 0x51, 0x99, 0xd8, 0x2e, 0x99, 0x3e, 0x9a, 0x17, 0x72, 0xb6, 0xb1, 0xa3, 0x34, 0x87, - 0x92, 0xaa, 0xf8, 0x38, 0x7e, 0x3b, 0x30, 0x64, 0x40, 0x9d, 0xac, 0xaa, 0x06, 0xd8, 0x9d, 0x7c, - 0x37, 0x07, 0xcf, 0x0c, 0xa0, 0x61, 0x03, 0xc7, 0x86, 0x5e, 0x1d, 0x38, 0x3c, 0xb0, 0x11, 0x4a, - 0xde, 0x85, 0x99, 0x4d, 0x71, 0xbb, 0x90, 0xc3, 0x91, 0x8f, 0x17, 0xae, 0xbc, 0x78, 0x48, 0xcb, - 0x28, 0x33, 0x89, 0xac, 0x45, 0x7a, 0x2a, 0x0c, 0x8c, 0xf4, 0xa4, 0x06, 0x4e, 0x1a, 0x19, 0x36, - 0x70, 0xd2, 0x17, 0x61, 0x5e, 0x6f, 0x9b, 0x88, 0x5f, 0x1d, 0x87, 0x8d, 0xca, 0xf5, 0x0f, 0x1b, - 0x35, 0x30, 0x4a, 0xae, 0xf1, 0x13, 0x39, 0x28, 0xeb, 0xbc, 0x3f, 0xee, 0x78, 0xbe, 0xa3, 0x8d, - 0xe7, 0x33, 0xd9, 0xe3, 0xd9, 0x7f, 0x20, 0xff, 0x8f, 0x5c, 0xb2, 0xb1, 0x43, 0x8d, 0xa0, 0x01, - 0x63, 0x55, 0xaf, 0x63, 0x3b, 0x72, 0xe0, 0xd0, 0x93, 0xa6, 0x85, 0x10, 0x53, 0x94, 0x0c, 0x17, - 0x65, 0xeb, 0x3c, 0x8c, 0xde, 0xf5, 0xdc, 0x4a, 0x55, 0x58, 0x14, 0x23, 0x1f, 0xd7, 0x73, 0x2d, - 0xbb, 0x65, 0xf2, 0x02, 0xb2, 0x0e, 0xd0, 0x68, 0xfa, 0x94, 0xba, 0x0d, 0xe7, 0x07, 0x69, 0x42, - 0x90, 0x61, 0x3d, 0xd4, 0xee, 0xe1, 0xc6, 0xc2, 0xdf, 0x71, 0x11, 0xd1, 0x0a, 0x9c, 0x1f, 0x54, - 0x37, 0x7e, 0x85, 0x1e, 0xd7, 0x95, 0x08, 0x44, 0x98, 0x18, 0x87, 0xab, 0x9f, 0xc4, 0xba, 0xca, - 0xac, 0x0a, 0x7b, 0xf8, 0x6a, 0xe6, 0x70, 0xfc, 0x7e, 0x0e, 0x9e, 0x19, 0x40, 0xf3, 0x04, 0x46, - 0xe5, 0xcf, 0xba, 0xc3, 0x29, 0x40, 0x4c, 0x84, 0x69, 0xc9, 0x9d, 0x56, 0xc8, 0x93, 0x55, 0x4e, - 0x89, 0xb4, 0xe4, 0x0c, 0xa0, 0xa5, 0x25, 0x67, 0x00, 0x76, 0xa8, 0xdf, 0xa2, 0xce, 0xee, 0x1e, - 0x37, 0x18, 0x9b, 0xe2, 0x7b, 0xc3, 0x1e, 0x42, 0xd4, 0x43, 0x9d, 0xe3, 0x18, 0xff, 0x72, 0x0c, - 0xce, 0x9a, 0x74, 0xd7, 0x61, 0xd7, 0x9e, 0xad, 0xc0, 0x71, 0x77, 0xb5, 0xc0, 0x53, 0x46, 0x62, - 0xe5, 0x8a, 0x2c, 0x2d, 0x0c, 0x12, 0xcd, 0xc4, 0x4b, 0x50, 0x64, 0xc7, 0xaa, 0xb2, 0x78, 0xf1, - 0x09, 0xcd, 0xf5, 0x5a, 0x54, 0x44, 0x36, 0x97, 0xc5, 0xe4, 0x15, 0x21, 0x85, 0x29, 0x79, 0xb4, - 0x98, 0x14, 0xf6, 0xbd, 0xc3, 0x25, 0xe0, 0x49, 0xc9, 0x59, 0xa9, 0x90, 0xc4, 0xa2, 0xab, 0xd2, - 0x48, 0x9f, 0xab, 0xd2, 0x06, 0xcc, 0x57, 0x5a, 0xfc, 0x74, 0xb4, 0xdb, 0x75, 0xdf, 0x71, 0x9b, - 0x4e, 0xd7, 0x6e, 0xcb, 0xeb, 0x3f, 0xf6, 0xb2, 0x1d, 0x95, 0x5b, 0xdd, 0x08, 0xc1, 0xcc, 0x24, - 0x63, 0xcd, 0xa8, 0xde, 0x6d, 0x60, 0x54, 0x23, 0xf1, 0x3a, 0x8a, 0xcd, 0x68, 0xb9, 0x01, 0xb6, - 0x22, 0x30, 0xa3, 0x62, 0xbc, 0xa4, 0xe1, 0x5b, 0xf8, 0xe6, 0x7a, 0xe3, 0x8e, 0xc8, 0xf4, 0x27, - 0xd3, 0x7c, 0x70, 0x2b, 0x87, 0xb0, 0x1d, 0xa0, 0x71, 0xa6, 0x86, 0x17, 0xd3, 0x35, 0x1a, 0xb7, - 0x18, 0x5d, 0x31, 0x45, 0x17, 0x04, 0x7b, 0x2a, 0x1d, 0xc7, 0x23, 0x57, 0xd8, 0x54, 0xe8, 0x78, - 0x21, 0xc5, 0x29, 0x3c, 0x11, 0x5f, 0xe9, 0x7c, 0x84, 0xf2, 0x2b, 0x9d, 0x82, 0x42, 0xde, 0x86, - 0xb9, 0xb5, 0xd5, 0x65, 0xa9, 0xd3, 0xae, 0x7a, 0xcd, 0x1e, 0x5a, 0x25, 0x00, 0xd6, 0x87, 0x63, - 0x48, 0x9b, 0xcb, 0x6c, 0x37, 0xc9, 0x42, 0x23, 0x17, 0x60, 0xbc, 0x56, 0x55, 0x65, 0x2d, 0x91, - 0xcb, 0x4e, 0x98, 0x5a, 0xc9, 0x42, 0x72, 0x2f, 0xbe, 0x73, 0x94, 0x8e, 0xbd, 0x1c, 0x9c, 0x1d, - 0xe2, 0xbe, 0xf1, 0x46, 0x52, 0x56, 0x54, 0x02, 0xcb, 0x27, 0x64, 0xc5, 0xa4, 0x84, 0xf8, 0x79, - 0x24, 0xbd, 0x49, 0x5d, 0xea, 0xc7, 0x01, 0xe5, 0x47, 0x79, 0xdf, 0x32, 0xd2, 0xdd, 0xa8, 0xc4, - 0xd4, 0x11, 0x89, 0x09, 0xa7, 0xea, 0x3e, 0x7d, 0xe8, 0x78, 0xbd, 0x40, 0xaf, 0x7c, 0x26, 0x96, - 0xa7, 0xbb, 0x02, 0xc1, 0x4a, 0x7e, 0x45, 0x36, 0xa9, 0xc8, 0xdd, 0xc7, 0x33, 0xee, 0xae, 0x7a, - 0x2d, 0x1a, 0xf0, 0x1d, 0xe8, 0xfb, 0x28, 0x77, 0x9f, 0xd2, 0xb6, 0x01, 0xbb, 0xf2, 0x7f, 0x86, - 0xb9, 0xfb, 0x52, 0xb8, 0xe4, 0xf3, 0x30, 0x8a, 0x3f, 0x85, 0xc4, 0x3c, 0x97, 0xc1, 0x36, 0x96, - 0x96, 0x9b, 0x0c, 0xd3, 0xe4, 0x04, 0xa4, 0x06, 0xe3, 0xe2, 0x2e, 0x78, 0x92, 0x0c, 0x54, 0xe2, - 0x52, 0xc9, 0x67, 0x9b, 0xa0, 0x37, 0x5a, 0x50, 0x52, 0x2b, 0x64, 0xab, 0xec, 0x96, 0x1d, 0xec, - 0xd1, 0x16, 0xfb, 0x25, 0x92, 0x47, 0xe2, 0x2a, 0xdb, 0x43, 0xa8, 0xc5, 0xbe, 0xc3, 0x54, 0x50, - 0xd8, 0x39, 0x5d, 0x0b, 0xb6, 0x02, 0xf1, 0x29, 0x42, 0x3b, 0xe4, 0xa0, 0xa6, 0xb1, 0x65, 0x8a, - 0x22, 0xe3, 0x07, 0x60, 0xfe, 0x6e, 0xaf, 0xdd, 0xb6, 0xb7, 0xdb, 0x54, 0x26, 0x17, 0xc2, 0x2c, - 0xfe, 0x2b, 0x30, 0x8a, 0x7f, 0x60, 0x45, 0xd3, 0x71, 0x82, 0x57, 0x05, 0x07, 0x4d, 0x6d, 0x73, - 0x18, 0xb5, 0x8a, 0xfd, 0xd4, 0xa2, 0x56, 0x31, 0x80, 0xf1, 0x7b, 0x39, 0x98, 0x97, 0x16, 0x0e, - 0xbe, 0xdd, 0xdc, 0xa7, 0xbe, 0x10, 0xb8, 0x2e, 0x68, 0x73, 0x0d, 0x17, 0x41, 0x62, 0x1a, 0xf1, - 0x59, 0x77, 0x5b, 0x7e, 0x84, 0x2e, 0x04, 0x65, 0x7d, 0xf0, 0x71, 0x1f, 0x43, 0xde, 0x86, 0x49, - 0x71, 0xe4, 0x2a, 0x51, 0x63, 0x31, 0x68, 0x9e, 0xb8, 0xcb, 0x26, 0xed, 0x6d, 0x54, 0x74, 0x94, - 0xef, 0xf4, 0xa6, 0x7c, 0x5c, 0xb9, 0x22, 0x5b, 0xbe, 0xd3, 0xeb, 0x18, 0x30, 0x75, 0xbf, 0x33, - 0x99, 0xec, 0x5b, 0x31, 0x77, 0xaf, 0xab, 0x71, 0x22, 0x73, 0xf1, 0x5d, 0x34, 0x8e, 0x13, 0xa9, - 0xde, 0x45, 0x23, 0xd4, 0x68, 0x4c, 0xf2, 0xc7, 0x8c, 0xc9, 0xbb, 0x72, 0x4c, 0x0a, 0xfd, 0x27, - 0xc6, 0xdc, 0x80, 0x71, 0x68, 0xc4, 0x2b, 0x64, 0x64, 0x28, 0x4d, 0xd0, 0xa7, 0x30, 0x21, 0x06, - 0x27, 0x49, 0xee, 0xcc, 0x82, 0x93, 0xaa, 0x5e, 0x1a, 0x1d, 0x9e, 0xe9, 0x31, 0xdb, 0xfd, 0x9b, - 0x50, 0xaa, 0x84, 0xa1, 0xdd, 0xdc, 0xa3, 0xad, 0x2a, 0xdb, 0x9e, 0x94, 0x40, 0x70, 0xb6, 0x80, - 0xab, 0xcf, 0x82, 0x2a, 0x2e, 0x0f, 0xd1, 0x6c, 0x07, 0xc2, 0x42, 0x37, 0x0a, 0xd1, 0xcc, 0x20, - 0x7a, 0x88, 0x66, 0x06, 0x21, 0x57, 0x60, 0xbc, 0xe6, 0x3e, 0x74, 0x58, 0x9f, 0xf0, 0x58, 0x70, - 0xa8, 0x4e, 0x73, 0x38, 0x48, 0xdd, 0x5c, 0x05, 0x16, 0x79, 0x43, 0xb9, 0x28, 0x4d, 0xc4, 0x0a, - 0x0b, 0xae, 0xa5, 0x8b, 0x62, 0x0a, 0xa9, 0x97, 0xa0, 0xe8, 0xe6, 0x74, 0x1d, 0xc6, 0xa5, 0xf2, - 0x15, 0xe2, 0x13, 0x44, 0x50, 0xa6, 0x23, 0x70, 0x48, 0x64, 0x4c, 0xf4, 0xaf, 0x24, 0xc1, 0x9c, - 0x54, 0x12, 0xfd, 0x2b, 0x49, 0x30, 0xb5, 0x44, 0xff, 0x4a, 0x3a, 0xcc, 0x48, 0x6f, 0x55, 0x3a, - 0x56, 0x6f, 0x75, 0x1f, 0x4a, 0x75, 0xdb, 0x0f, 0x1d, 0x26, 0xf7, 0xb8, 0x61, 0xb0, 0x30, 0xa5, - 0xa9, 0x7a, 0x95, 0xa2, 0x95, 0xe7, 0x64, 0xb2, 0xf9, 0xae, 0x82, 0xaf, 0x67, 0x45, 0x8f, 0xe1, - 0xd9, 0xf6, 0xb9, 0xd3, 0x1f, 0xc7, 0x3e, 0x17, 0x3b, 0x15, 0xd5, 0x7b, 0x33, 0xb1, 0xba, 0x09, - 0x2f, 0x42, 0x09, 0x1d, 0x5f, 0x84, 0x48, 0xbe, 0x0c, 0x25, 0xf6, 0x77, 0xdd, 0x6b, 0x3b, 0x4d, - 0x87, 0x06, 0x0b, 0x65, 0x6c, 0xdc, 0x73, 0x99, 0xab, 0x1f, 0x91, 0x0e, 0x1a, 0x34, 0xe4, 0x0b, - 0x18, 0x19, 0x27, 0xf5, 0xf6, 0x1a, 0x37, 0xf2, 0x1e, 0x94, 0xd8, 0xec, 0xdb, 0xb6, 0x03, 0x2e, - 0xee, 0xce, 0xc6, 0x16, 0xd6, 0x2d, 0x01, 0x4f, 0x45, 0x49, 0x57, 0x09, 0xd8, 0x31, 0x5f, 0xe9, - 0xf2, 0x0d, 0x92, 0x28, 0xb3, 0xbd, 0x9b, 0xda, 0x1c, 0x25, 0x1a, 0xf9, 0x02, 0x94, 0x2a, 0xdd, - 0x6e, 0xbc, 0xe3, 0xcc, 0xfd, 0x7f, 0xec, 0xbd, 0x6f, 0x8c, 0x1c, 0xc9, 0x75, 0x18, 0xce, 0x9e, - 0x99, 0xdd, 0x9d, 0x7d, 0xfb, 0xaf, 0xb7, 0xb8, 0x24, 0x97, 0x4b, 0x1e, 0xff, 0xf4, 0xdd, 0x51, - 0x77, 0x7b, 0x3a, 0xde, 0x91, 0xf7, 0x3b, 0x9d, 0x28, 0xe9, 0xee, 0xdc, 0x3b, 0xd3, 0xbb, 0x3b, - 0xe4, 0xec, 0xcc, 0xa8, 0x7a, 0x96, 0x34, 0x75, 0x96, 0xdb, 0xcd, 0x99, 0xde, 0xdd, 0x3e, 0xce, - 0x4e, 0xcf, 0x4d, 0xf7, 0x1c, 0x6f, 0x05, 0x03, 0x3f, 0xd9, 0x42, 0x64, 0x20, 0x81, 0x63, 0xc7, - 0x76, 0x10, 0xc1, 0x48, 0xe0, 0x00, 0x11, 0x0c, 0x7f, 0x08, 0x90, 0x20, 0xf9, 0x12, 0x44, 0x40, - 0x00, 0x23, 0x5f, 0x0c, 0x08, 0x0a, 0x12, 0x04, 0xf0, 0x07, 0x39, 0x38, 0xd8, 0x12, 0x02, 0x04, - 0x82, 0xbf, 0x19, 0xc9, 0x07, 0x03, 0x0e, 0x82, 0x7a, 0x55, 0xd5, 0x5d, 0xdd, 0xd3, 0x33, 0x5c, - 0x8a, 0xa7, 0x24, 0x0e, 0xf4, 0x85, 0xdc, 0x79, 0xf5, 0xde, 0xeb, 0xfa, 0x5f, 0xaf, 0xde, 0x7b, - 0xf5, 0x9e, 0xa2, 0xe5, 0x1b, 0x0c, 0x9c, 0xdc, 0x5d, 0x27, 0x45, 0x91, 0xdd, 0x98, 0xd7, 0x9e, - 0x69, 0x63, 0x26, 0xaf, 0xc7, 0x37, 0x80, 0x73, 0x89, 0x22, 0x5a, 0x5c, 0x46, 0x53, 0xd7, 0x09, - 0x7e, 0x19, 0xa8, 0xc0, 0x12, 0xd7, 0xcc, 0x4a, 0x69, 0xe6, 0xfc, 0xd8, 0xea, 0xc9, 0x11, 0x6a, - 0xd2, 0x34, 0xc4, 0x82, 0x65, 0xfe, 0xc8, 0xbd, 0x27, 0xc2, 0xd7, 0xaf, 0x5f, 0xc0, 0x55, 0x8b, - 0x5c, 0xf8, 0xdb, 0xf8, 0x1e, 0x66, 0x35, 0x72, 0x53, 0x5c, 0x32, 0x44, 0xc6, 0x8f, 0x35, 0xb8, - 0x30, 0x61, 0xc4, 0xe3, 0xe0, 0xe6, 0xda, 0xf4, 0xe0, 0xe6, 0x6c, 0xe7, 0x48, 0x6b, 0x5a, 0xb0, - 0xfd, 0xe3, 0x4f, 0xcf, 0x62, 0x79, 0x2b, 0x00, 0x22, 0x12, 0x87, 0x89, 0x4f, 0xdf, 0x0d, 0x50, - 0x9b, 0x5c, 0x1c, 0x3f, 0x84, 0x04, 0x1e, 0xaf, 0x14, 0x0f, 0x09, 0x2b, 0xf2, 0x92, 0xc5, 0xc3, - 0xfa, 0x61, 0x90, 0x5a, 0xc1, 0x39, 0xac, 0x8d, 0x4f, 0x35, 0x58, 0x50, 0xd6, 0x21, 0xb9, 0xa6, - 0x3c, 0x6c, 0xd6, 0x79, 0x66, 0x3b, 0x85, 0x43, 0x81, 0x9f, 0x44, 0xb8, 0xa8, 0x0a, 0x4f, 0xd7, - 0x99, 0x63, 0xb8, 0x2f, 0x25, 0x00, 0x7c, 0x26, 0xbe, 0x17, 0x96, 0x93, 0xaf, 0x03, 0xd4, 0xdd, - 0x30, 0x32, 0x3b, 0x91, 0xff, 0xb1, 0x77, 0x8a, 0x43, 0x47, 0x86, 0xc4, 0x3c, 0x87, 0xb9, 0x54, - 0x5c, 0x24, 0xcb, 0x9c, 0x11, 0x0a, 0x43, 0xe3, 0xd7, 0x35, 0x80, 0xfd, 0x5a, 0x05, 0x33, 0x38, - 0x3c, 0xaf, 0x50, 0x90, 0x1f, 0x15, 0x5b, 0x72, 0x9f, 0x22, 0x0e, 0xfc, 0xa9, 0x06, 0xcb, 0x69, - 0x34, 0xf2, 0x1e, 0xac, 0xd8, 0x9d, 0x61, 0xd0, 0xeb, 0x3d, 0x72, 0x3b, 0x8f, 0xeb, 0x7e, 0xdf, - 0xe3, 0x91, 0x82, 0x67, 0xf8, 0x59, 0x14, 0xc6, 0x45, 0x4e, 0x8f, 0x95, 0xd1, 0x2c, 0x32, 0xf9, - 0x96, 0x06, 0x4b, 0xf6, 0x51, 0xf0, 0x24, 0x0e, 0xbc, 0x2b, 0x06, 0xe4, 0xeb, 0x6c, 0x6d, 0x87, - 0x47, 0xc1, 0x93, 0x24, 0x2d, 0x6e, 0xca, 0xbd, 0xf5, 0xdd, 0xd3, 0x79, 0x1e, 0x74, 0x02, 0xbc, - 0x8f, 0x44, 0xe1, 0xcd, 0xd4, 0x47, 0x68, 0xfa, 0x9b, 0xc6, 0xdf, 0x68, 0xb0, 0x80, 0x37, 0x97, - 0x5e, 0x0f, 0x65, 0xae, 0xff, 0x97, 0x72, 0xac, 0xc6, 0xed, 0x9a, 0x32, 0xb0, 0x6f, 0xc3, 0x4a, - 0x06, 0x8d, 0x18, 0x30, 0x6b, 0x63, 0xcc, 0x02, 0x55, 0xe9, 0xc1, 0xa3, 0x18, 0x50, 0x51, 0x62, - 0x58, 0x0a, 0xd9, 0xfd, 0x5b, 0x68, 0x89, 0xbe, 0x0d, 0xe0, 0x4b, 0x90, 0xbc, 0xd9, 0x90, 0x6c, - 0x4d, 0xee, 0xdf, 0xa2, 0x0a, 0x96, 0xd1, 0x80, 0x59, 0x3b, 0x18, 0x46, 0x5b, 0x27, 0xfc, 0x32, - 0x51, 0xf5, 0xc2, 0x8e, 0x6a, 0x6a, 0xf6, 0xd1, 0x10, 0xd4, 0xa1, 0xa2, 0x88, 0x5c, 0x85, 0x99, - 0x6d, 0xdf, 0xeb, 0x75, 0x55, 0x17, 0xe4, 0x03, 0x06, 0xa0, 0x1c, 0xce, 0x2e, 0x5c, 0xe7, 0x93, - 0x44, 0x47, 0x89, 0xaf, 0xf3, 0xf3, 0xae, 0x9b, 0x4a, 0xaa, 0x7f, 0xaf, 0xc7, 0xc9, 0x45, 0xc6, - 0xbf, 0x34, 0xa5, 0xab, 0xff, 0xa5, 0x06, 0x1b, 0x93, 0x49, 0x54, 0xf7, 0x69, 0x6d, 0x8a, 0xfb, - 0xf4, 0xcb, 0x59, 0xd3, 0x28, 0xa2, 0x09, 0xd3, 0x68, 0x62, 0x10, 0xad, 0xa2, 0xf7, 0x7a, 0xc7, - 0x93, 0xd9, 0x8d, 0xae, 0x4d, 0xa9, 0x33, 0x22, 0xf2, 0x61, 0x8e, 0x90, 0x86, 0x0a, 0x5a, 0xe3, - 0xdf, 0x95, 0xe0, 0xe2, 0x44, 0x0a, 0xb2, 0xab, 0xe4, 0x4c, 0x5b, 0x8e, 0xb3, 0x35, 0x4d, 0xc4, - 0xbf, 0x89, 0xff, 0xa2, 0x83, 0x62, 0xf6, 0x49, 0x5c, 0x33, 0xce, 0x95, 0x55, 0x40, 0x5e, 0xaf, - 0x3d, 0x95, 0x17, 0x47, 0x47, 0x66, 0x30, 0x9e, 0x36, 0x0b, 0x5f, 0x5f, 0x7a, 0x91, 0xeb, 0xf7, - 0x42, 0x75, 0xd9, 0x75, 0x39, 0x88, 0xca, 0xb2, 0xc4, 0xa7, 0xbd, 0x94, 0xef, 0xd3, 0x6e, 0xfc, - 0x4f, 0x0d, 0xe6, 0xe3, 0x6a, 0x93, 0x0d, 0x38, 0xdf, 0xa6, 0x66, 0xc5, 0x72, 0xda, 0x0f, 0x5b, - 0x96, 0xb3, 0xdf, 0xb0, 0x5b, 0x56, 0xa5, 0xb6, 0x5d, 0xb3, 0xaa, 0xfa, 0x19, 0xb2, 0x0a, 0x4b, - 0xfb, 0x8d, 0x7b, 0x8d, 0xe6, 0x83, 0x86, 0x63, 0x51, 0xda, 0xa4, 0xba, 0x46, 0x96, 0x60, 0x9e, - 0x6e, 0x99, 0x15, 0xa7, 0xd1, 0xac, 0x5a, 0x7a, 0x81, 0xe8, 0xb0, 0x58, 0x69, 0x36, 0x1a, 0x56, - 0xa5, 0x5d, 0xbb, 0x5f, 0x6b, 0x3f, 0xd4, 0x8b, 0x84, 0xc0, 0x32, 0x22, 0xb4, 0x68, 0xad, 0x51, - 0xa9, 0xb5, 0xcc, 0xba, 0x5e, 0x62, 0x30, 0x86, 0xaf, 0xc0, 0x66, 0x62, 0x46, 0xf7, 0xf6, 0xb7, - 0x2c, 0x7d, 0x96, 0xa1, 0xb0, 0xbf, 0x14, 0x94, 0x39, 0xf6, 0x79, 0x44, 0xa9, 0x9a, 0x6d, 0x73, - 0xcb, 0xb4, 0x2d, 0xbd, 0x4c, 0x2e, 0xc0, 0xd9, 0x14, 0xc8, 0xa9, 0x37, 0x77, 0x6a, 0x0d, 0x7d, - 0x9e, 0xac, 0x81, 0x1e, 0xc3, 0xaa, 0x5b, 0xce, 0xbe, 0x6d, 0x51, 0x1d, 0xb2, 0xd0, 0x86, 0xb9, - 0x67, 0xe9, 0x0b, 0xc6, 0xbb, 0xfc, 0xb1, 0x22, 0xef, 0x6a, 0x72, 0x1e, 0x88, 0xdd, 0x36, 0xdb, - 0xfb, 0x76, 0xa6, 0xf1, 0x0b, 0x30, 0x67, 0xef, 0x57, 0x2a, 0x96, 0x6d, 0xeb, 0x1a, 0x01, 0x98, - 0xdd, 0x36, 0x6b, 0x75, 0xab, 0xaa, 0x17, 0x8c, 0xdf, 0xd6, 0x60, 0x55, 0x4a, 0x80, 0xd2, 0x10, - 0xf5, 0x9c, 0x6b, 0xf1, 0xbd, 0xd4, 0xc5, 0x56, 0xbe, 0x3c, 0xcb, 0x7c, 0x64, 0xca, 0x32, 0xfc, - 0xc7, 0x1a, 0x9c, 0xcb, 0xc5, 0x26, 0x0f, 0x41, 0x97, 0x35, 0x88, 0x5f, 0x91, 0x6a, 0x29, 0x01, - 0x5a, 0xd2, 0x65, 0xd0, 0xb8, 0xaa, 0x34, 0xc9, 0xe2, 0x3e, 0xc6, 0xe6, 0xf4, 0x39, 0x46, 0x8c, - 0xef, 0x68, 0x70, 0x61, 0xc2, 0x67, 0x48, 0x05, 0x66, 0xe3, 0x6c, 0x53, 0x53, 0x7c, 0xf4, 0xd6, - 0x7e, 0xf8, 0xe9, 0x55, 0x81, 0x88, 0x69, 0xaf, 0xf1, 0x2f, 0x3a, 0x1b, 0xa7, 0x8f, 0xc2, 0x1c, - 0x4e, 0xbc, 0xfb, 0x2e, 0x66, 0x7a, 0x5e, 0x7c, 0xc9, 0x7c, 0x60, 0x6f, 0x2d, 0x88, 0xbe, 0x2b, - 0xba, 0x4f, 0x42, 0x4c, 0xe2, 0x64, 0xfc, 0x9e, 0xc6, 0x84, 0xbb, 0x2c, 0x22, 0x93, 0x79, 0xcd, - 0x30, 0x1c, 0x1d, 0x7b, 0x34, 0xe8, 0x79, 0x26, 0x6d, 0x88, 0x63, 0x03, 0xa5, 0x55, 0x17, 0x0b, - 0xf0, 0x5a, 0xe1, 0xb8, 0xc3, 0x54, 0xb0, 0x82, 0x14, 0x0d, 0xb9, 0x03, 0x60, 0x7d, 0x12, 0x79, - 0xc3, 0xbe, 0xdb, 0x8b, 0xc3, 0xce, 0xf0, 0x80, 0x5e, 0x02, 0x9a, 0x96, 0xb7, 0x15, 0x64, 0xe3, - 0xdb, 0x1a, 0x2c, 0x8a, 0x4b, 0x93, 0xd9, 0xf3, 0x86, 0xd1, 0xf3, 0x4d, 0xaf, 0x3b, 0xa9, 0xe9, - 0x15, 0x3f, 0x49, 0x51, 0xf8, 0xb3, 0xe2, 0xdc, 0x99, 0xf5, 0x1f, 0x34, 0xd0, 0xb3, 0x88, 0xe4, - 0x3d, 0x28, 0xdb, 0xde, 0xc7, 0xde, 0xd0, 0x8f, 0x4e, 0xc4, 0x46, 0x29, 0xf3, 0x72, 0x72, 0x1c, - 0x51, 0xc6, 0xe7, 0x43, 0x28, 0x7e, 0xd1, 0x98, 0xe6, 0xb4, 0xfb, 0xbd, 0xa2, 0xf6, 0x28, 0x7e, - 0x56, 0x6a, 0x0f, 0xe3, 0xcf, 0x0b, 0x70, 0x61, 0xc7, 0x8b, 0xd4, 0x36, 0xc5, 0xbe, 0x13, 0x6f, - 0x9e, 0xae, 0x5d, 0x4a, 0x4b, 0xd6, 0x61, 0x0e, 0x8b, 0xe4, 0xf8, 0x52, 0xf9, 0x93, 0x6c, 0xc5, - 0xf3, 0xba, 0x98, 0x4a, 0xfc, 0x37, 0xe1, 0xdb, 0x37, 0x95, 0x54, 0x60, 0xf1, 0xb4, 0xbe, 0x01, - 0xcb, 0x98, 0x85, 0x62, 0xc4, 0x96, 0x83, 0xd7, 0x15, 0xea, 0x9f, 0x32, 0xcd, 0x40, 0xc9, 0x26, - 0xe8, 0x0c, 0x62, 0x76, 0x1e, 0xf7, 0x83, 0x27, 0x3d, 0xaf, 0x7b, 0xe8, 0x75, 0xf1, 0x58, 0x2f, - 0xd3, 0x31, 0xb8, 0xe4, 0xb9, 0xdf, 0xe7, 0x57, 0x37, 0xaf, 0x8b, 0x3a, 0x1a, 0xc1, 0x33, 0x81, - 0x6e, 0xdc, 0x81, 0x85, 0x9f, 0x32, 0xad, 0x9f, 0xf1, 0x67, 0x1a, 0xac, 0x61, 0xe3, 0x94, 0x0f, - 0xcb, 0x94, 0xcb, 0xb2, 0xb7, 0x94, 0x4c, 0x57, 0x2e, 0x03, 0xa5, 0x97, 0x42, 0xdc, 0x8b, 0x89, - 0x4e, 0xa8, 0x70, 0x0a, 0x9d, 0x90, 0xa2, 0xd2, 0x2a, 0x7d, 0x56, 0x2a, 0xad, 0xbb, 0xa5, 0x72, - 0x51, 0x2f, 0x25, 0x43, 0x6e, 0x7c, 0xab, 0x00, 0x73, 0xd4, 0xc3, 0xbc, 0xfb, 0xe4, 0x06, 0xcc, - 0x35, 0x82, 0xc8, 0x0b, 0xf7, 0xaa, 0xaa, 0x5f, 0x72, 0x9f, 0x81, 0x9c, 0xe3, 0x2e, 0x95, 0x85, - 0x6c, 0xc2, 0xb7, 0x86, 0x41, 0x77, 0xd4, 0x89, 0xd4, 0x09, 0x3f, 0xe0, 0x20, 0x2a, 0xcb, 0xc8, - 0xe7, 0x61, 0x5e, 0x70, 0x8e, 0x0d, 0xc5, 0xe8, 0x6e, 0x3d, 0xe4, 0x40, 0xcc, 0x57, 0x13, 0x23, - 0xa0, 0x4c, 0xcb, 0x05, 0x8c, 0x92, 0x22, 0xd3, 0x8e, 0xc9, 0x0c, 0x52, 0x54, 0x9f, 0x99, 0x22, - 0xaa, 0xbf, 0x09, 0xb3, 0x66, 0x18, 0x7a, 0x91, 0x8c, 0xd5, 0xb0, 0x18, 0x47, 0xcb, 0x0b, 0xbd, - 0x88, 0x33, 0x76, 0xb1, 0x9c, 0x0a, 0x3c, 0xe3, 0xaf, 0x0a, 0x30, 0x83, 0x7f, 0xa2, 0x19, 0x76, - 0xd8, 0x39, 0x4a, 0x99, 0x61, 0x87, 0x9d, 0x23, 0x8a, 0x50, 0x72, 0x0b, 0x35, 0x15, 0x32, 0x29, - 0x9b, 0x68, 0x3d, 0xaa, 0xe0, 0xbb, 0x09, 0x98, 0xaa, 0x38, 0xb1, 0xd7, 0x40, 0x31, 0x37, 0x42, - 0xcb, 0x79, 0x28, 0x34, 0x6d, 0xd1, 0x62, 0x0c, 0xf2, 0x15, 0x84, 0xb4, 0xd0, 0xb4, 0xb1, 0x37, - 0x76, 0xcd, 0xdb, 0x6f, 0x7f, 0x41, 0x34, 0x94, 0xf7, 0xc6, 0x91, 0x7b, 0xfb, 0xed, 0x2f, 0x50, - 0x51, 0xc2, 0xfa, 0x17, 0xeb, 0x8c, 0xc6, 0x5c, 0x1e, 0x48, 0x00, 0xfb, 0x17, 0xdb, 0x86, 0x86, - 0x5b, 0x9a, 0x20, 0x90, 0xdb, 0xb0, 0x20, 0x22, 0x5a, 0x20, 0xbe, 0x12, 0x71, 0x42, 0x44, 0xbc, - 0xe0, 0x14, 0x2a, 0x12, 0x37, 0xeb, 0x89, 0x01, 0x92, 0xa9, 0xa3, 0x85, 0x59, 0x4f, 0x0e, 0x61, - 0x48, 0x15, 0x14, 0x56, 0x25, 0x6e, 0x17, 0x4c, 0x02, 0x04, 0x60, 0x95, 0x84, 0xf1, 0x10, 0x33, - 0x7e, 0xc4, 0x08, 0xc6, 0x1f, 0x15, 0xa0, 0xdc, 0xea, 0x8d, 0x0e, 0xfd, 0xfe, 0xfd, 0x5b, 0x84, - 0x00, 0x5e, 0xe3, 0x64, 0x4a, 0x18, 0xf6, 0x37, 0xb9, 0x08, 0x65, 0x79, 0x73, 0x93, 0x1b, 0x52, - 0x28, 0x6e, 0x6d, 0xeb, 0x20, 0xc7, 0x5d, 0x44, 0x73, 0x93, 0x3f, 0xc9, 0x2d, 0x88, 0xef, 0x5f, - 0x93, 0x2e, 0x6a, 0x25, 0xb6, 0x58, 0x68, 0x8c, 0x46, 0x5e, 0x07, 0x3c, 0x24, 0xc4, 0xe5, 0x41, - 0x2a, 0xb4, 0x79, 0xd5, 0x84, 0x9c, 0xc2, 0x49, 0x10, 0x8d, 0xbc, 0x05, 0x62, 0x62, 0x62, 0xaf, - 0x27, 0xa7, 0x97, 0x20, 0xe0, 0x49, 0x5f, 0x25, 0x89, 0x40, 0x25, 0x5f, 0x81, 0x85, 0xce, 0xd0, - 0x43, 0x4b, 0xa6, 0xdb, 0x93, 0x2f, 0x56, 0x37, 0x52, 0x94, 0x95, 0xa4, 0xfc, 0xfe, 0x2d, 0xaa, - 0xa2, 0x1b, 0xdf, 0x9f, 0x87, 0x45, 0xb5, 0x3e, 0x84, 0xc2, 0xd9, 0xb0, 0xc7, 0xee, 0xee, 0xc2, - 0x93, 0x6e, 0x80, 0x85, 0xe2, 0x38, 0xbd, 0x96, 0xae, 0x10, 0xc3, 0xe3, 0x6e, 0x75, 0x32, 0x14, - 0xc7, 0xee, 0x19, 0xba, 0x1a, 0x26, 0x60, 0x8e, 0x47, 0x4c, 0x28, 0x07, 0x83, 0xf0, 0xd0, 0xeb, - 0xfb, 0xd2, 0xde, 0xf2, 0x62, 0x8a, 0x51, 0x53, 0x14, 0x8e, 0xf1, 0x8a, 0xc9, 0xc8, 0xdb, 0x30, - 0x1b, 0x0c, 0xbc, 0xbe, 0xeb, 0x8b, 0x33, 0xee, 0x52, 0x86, 0x81, 0xd7, 0x37, 0x6b, 0x0a, 0xa1, - 0x40, 0x26, 0x6f, 0x40, 0x29, 0x78, 0x1c, 0x8f, 0xd7, 0xc5, 0x34, 0xd1, 0xe3, 0xc8, 0x55, 0x48, - 0x10, 0x91, 0x11, 0x7c, 0xe8, 0x1e, 0x1f, 0x88, 0x11, 0x4b, 0x13, 0xdc, 0x75, 0x8f, 0x0f, 0x54, - 0x02, 0x86, 0x48, 0xde, 0x07, 0x18, 0xb8, 0x87, 0xde, 0xd0, 0xe9, 0x8e, 0xa2, 0x13, 0x31, 0x6e, - 0x57, 0x52, 0x64, 0x2d, 0x56, 0x5c, 0x1d, 0x45, 0x27, 0x0a, 0xed, 0xfc, 0x40, 0x02, 0x89, 0x09, - 0x70, 0xec, 0x46, 0x91, 0x37, 0x3c, 0x0e, 0x84, 0x2b, 0x63, 0x12, 0xfb, 0x91, 0x33, 0xd8, 0x8b, - 0x8b, 0x15, 0x0e, 0x0a, 0x11, 0x56, 0xda, 0x1f, 0xba, 0x68, 0x55, 0x1f, 0xab, 0xb4, 0x3f, 0x4c, - 0xb5, 0x92, 0x21, 0x92, 0x2f, 0xc2, 0x5c, 0xd7, 0x0f, 0x3b, 0xc1, 0xb0, 0x2b, 0x62, 0xb4, 0x5c, - 0x4e, 0xd1, 0x54, 0x79, 0x99, 0x42, 0x26, 0xd1, 0x59, 0x6d, 0x45, 0xec, 0xd7, 0x46, 0xf0, 0x04, - 0xd5, 0xfc, 0xd9, 0xda, 0xda, 0x71, 0xb1, 0x5a, 0xdb, 0x84, 0x88, 0x0d, 0xe5, 0xa1, 0x1f, 0xf5, - 0xdc, 0x47, 0xc2, 0x76, 0x9e, 0x1e, 0xca, 0x1d, 0x2c, 0x52, 0x87, 0x92, 0x23, 0x93, 0x3b, 0x50, - 0x96, 0xe9, 0x20, 0xc4, 0x3b, 0xd0, 0x74, 0xa5, 0x45, 0x3a, 0x07, 0xb5, 0xd2, 0x22, 0x01, 0x04, - 0xeb, 0x9f, 0xb0, 0xe3, 0x1f, 0x8b, 0xe7, 0x9b, 0xe9, 0xfe, 0xb1, 0x2b, 0xb5, 0x3d, 0xb5, 0x7f, - 0x18, 0x22, 0x79, 0x0f, 0xe6, 0xd8, 0xfa, 0xed, 0x06, 0x87, 0x22, 0xca, 0x85, 0x91, 0xee, 0x1f, - 0x5e, 0x36, 0x36, 0x5d, 0x25, 0x11, 0x5b, 0xc8, 0xee, 0x93, 0xd0, 0xf1, 0x3b, 0x18, 0x12, 0x34, - 0xbb, 0x1c, 0xcd, 0x07, 0x76, 0xad, 0xa2, 0x90, 0xcd, 0xb8, 0x4f, 0xc2, 0x5a, 0x87, 0xdc, 0x86, - 0x19, 0xcc, 0x96, 0x22, 0xe2, 0x7f, 0xa6, 0x69, 0x30, 0x4f, 0x8a, 0x4a, 0x83, 0xa8, 0x6c, 0x20, - 0x8f, 0x43, 0x7c, 0x11, 0x23, 0x72, 0x96, 0xa4, 0xfb, 0x64, 0xcf, 0xc6, 0x67, 0x32, 0x6a, 0x15, - 0x05, 0x3a, 0xab, 0x62, 0xdf, 0x8b, 0x1c, 0xff, 0x23, 0x91, 0x75, 0x24, 0xfd, 0xb9, 0x86, 0x17, - 0xd5, 0xbe, 0xaa, 0x7e, 0xae, 0xef, 0x45, 0xb5, 0x8f, 0xc4, 0xd0, 0x1d, 0x8d, 0x1e, 0xa1, 0x2e, - 0x3d, 0x67, 0xe8, 0x8e, 0x46, 0xd9, 0xa1, 0x3b, 0x1a, 0x3d, 0x62, 0x64, 0x7e, 0x3f, 0x1a, 0xf5, - 0x3d, 0xf1, 0x1e, 0x33, 0x4d, 0x56, 0xc3, 0x22, 0x95, 0x8c, 0x23, 0x93, 0x2b, 0x00, 0x89, 0xf3, - 0x02, 0x37, 0x0b, 0x51, 0x05, 0xf2, 0xa5, 0xd2, 0x7f, 0xfb, 0xa7, 0x57, 0xb5, 0x2d, 0x80, 0xb2, - 0x0c, 0x15, 0xc4, 0xc4, 0xf0, 0xb5, 0xbc, 0xba, 0x90, 0xeb, 0xb0, 0xa8, 0x06, 0x32, 0x12, 0x87, - 0xc1, 0x82, 0x3b, 0xf0, 0x65, 0x28, 0xa3, 0xe9, 0xf9, 0x28, 0x5e, 0x83, 0xd5, 0xd4, 0xb3, 0xa5, - 0xc4, 0x8f, 0x90, 0xea, 0x6a, 0x01, 0x9e, 0xbd, 0x15, 0x80, 0x30, 0x72, 0x87, 0x91, 0xd3, 0x75, - 0xa3, 0xd3, 0x68, 0x85, 0xcb, 0x6c, 0x3f, 0xe7, 0x5e, 0xe2, 0x48, 0x57, 0x75, 0x23, 0x8f, 0x37, - 0xce, 0xa8, 0xc3, 0xc5, 0x89, 0x7b, 0x2d, 0x79, 0x15, 0xf4, 0x03, 0x57, 0x68, 0x5a, 0x3b, 0x47, - 0x6e, 0xbf, 0xef, 0xf5, 0x44, 0xc3, 0x56, 0x24, 0xbc, 0xc2, 0xc1, 0x82, 0xdb, 0xfb, 0x4a, 0xef, - 0x28, 0x8b, 0xec, 0x14, 0xbd, 0x23, 0x18, 0x7c, 0x4f, 0x83, 0xcb, 0xd3, 0xb6, 0x6c, 0xb2, 0x01, - 0xe5, 0xc1, 0xd0, 0x0f, 0xf0, 0x6a, 0x20, 0xfa, 0x50, 0xfe, 0xc6, 0x74, 0x1d, 0x28, 0xc3, 0x46, - 0xee, 0xa1, 0x78, 0x07, 0x44, 0xe7, 0x11, 0xd2, 0x76, 0x0f, 0x43, 0xd6, 0xc5, 0x5d, 0xef, 0xc0, - 0x1d, 0xf5, 0x22, 0x27, 0xec, 0x1c, 0x79, 0x5d, 0x7c, 0xa9, 0x87, 0x0e, 0x98, 0x54, 0x17, 0x05, - 0xb6, 0x84, 0x8f, 0xd5, 0x78, 0x66, 0x42, 0x8d, 0xef, 0x96, 0xca, 0x9a, 0x5e, 0xa0, 0xe8, 0xf1, - 0x66, 0x7c, 0xb3, 0x00, 0xeb, 0x93, 0xf6, 0x28, 0xf2, 0x6e, 0x5e, 0x1f, 0x70, 0x63, 0x91, 0x0a, - 0x57, 0x8d, 0x45, 0xea, 0xec, 0xb9, 0x0d, 0xf1, 0x3b, 0xbb, 0xa7, 0xc5, 0xcc, 0x90, 0x30, 0x46, - 0x33, 0x70, 0xc3, 0xf0, 0x09, 0xdb, 0x86, 0x8b, 0x4a, 0xec, 0x66, 0x01, 0x53, 0x69, 0x24, 0x8c, - 0xbc, 0x03, 0xd0, 0xe9, 0x05, 0xa1, 0x87, 0x3e, 0x19, 0x42, 0xbe, 0xe3, 0xaf, 0x07, 0x62, 0xa8, - 0x6a, 0x84, 0x47, 0x68, 0x25, 0xe8, 0xca, 0xf9, 0xe4, 0xc2, 0x85, 0x09, 0x87, 0x12, 0x1b, 0x1e, - 0x7c, 0x38, 0xc7, 0xf7, 0x20, 0x91, 0xea, 0x8e, 0x41, 0x78, 0x8a, 0xa6, 0x6c, 0x8f, 0x17, 0x26, - 0xcd, 0x91, 0x13, 0x20, 0xe3, 0x27, 0x0f, 0xe3, 0x2e, 0xbc, 0xe5, 0x47, 0xc3, 0x98, 0x3b, 0x87, - 0xec, 0x0f, 0x7b, 0xe4, 0x2a, 0x2c, 0xc8, 0xa4, 0xbc, 0xec, 0xfe, 0xc4, 0x99, 0x83, 0x00, 0xdd, - 0xf3, 0x70, 0xf2, 0x60, 0xe0, 0x5b, 0x9e, 0x7a, 0x87, 0xaf, 0xbc, 0x79, 0x84, 0xb4, 0x4f, 0x06, - 0xb2, 0x75, 0x97, 0xe5, 0xfc, 0x4e, 0xcb, 0x03, 0xa2, 0xf4, 0x1f, 0x6a, 0x72, 0xf8, 0xc7, 0x0f, - 0xd4, 0xa7, 0xd5, 0x8f, 0x00, 0x3e, 0x66, 0x13, 0x15, 0xc3, 0xbf, 0x99, 0xa4, 0x28, 0x57, 0x9d, - 0x90, 0x14, 0xc5, 0x4f, 0x72, 0x03, 0x56, 0x86, 0xdc, 0x1f, 0x39, 0x0a, 0x44, 0x7f, 0xf2, 0xec, - 0x34, 0x4b, 0x1c, 0xdc, 0x0e, 0xb0, 0x4f, 0x45, 0xbd, 0xee, 0xc6, 0x1d, 0xa6, 0xc8, 0x17, 0xe4, - 0x26, 0xcc, 0x33, 0xf9, 0x02, 0x43, 0x26, 0x65, 0x5e, 0xd1, 0x20, 0x1e, 0x4a, 0x6b, 0xb4, 0xfc, - 0xa1, 0xf8, 0x5b, 0xf0, 0xfa, 0xf5, 0x78, 0x03, 0x4c, 0xef, 0xaa, 0xe4, 0x3c, 0xcc, 0xf2, 0x64, - 0xd2, 0xa2, 0x6d, 0xe2, 0x17, 0x79, 0x19, 0x96, 0xf9, 0xd3, 0xd7, 0xcc, 0xc0, 0x2e, 0x21, 0x34, - 0x9e, 0xde, 0xa7, 0x4b, 0x6d, 0x24, 0x2a, 0xf1, 0x6f, 0x0a, 0xb2, 0x45, 0xaa, 0x88, 0x45, 0x2e, - 0xc0, 0x5c, 0x30, 0x3c, 0x54, 0xfa, 0x77, 0x36, 0x18, 0x1e, 0xb2, 0xce, 0x7d, 0x05, 0x74, 0xfe, - 0xb2, 0x8c, 0x47, 0xf8, 0x08, 0x4f, 0xfa, 0x5c, 0x07, 0x53, 0xa6, 0xcb, 0x1c, 0xbe, 0x1f, 0x7a, - 0x43, 0xfb, 0xa4, 0xdf, 0x61, 0x98, 0x61, 0x18, 0x38, 0x6a, 0xf8, 0x35, 0x51, 0x91, 0xe5, 0x30, - 0x0c, 0x92, 0x38, 0x6c, 0x5d, 0xb2, 0x05, 0x4b, 0x8c, 0x4f, 0x1c, 0x45, 0x4e, 0x6c, 0xc3, 0x2f, - 0x8c, 0x4b, 0x80, 0x27, 0xfd, 0x8e, 0xac, 0x22, 0x5d, 0x0c, 0x95, 0x5f, 0xe4, 0x1e, 0xe8, 0x8a, - 0xa8, 0x8c, 0x4f, 0x8d, 0x33, 0x0e, 0xfa, 0x09, 0x1b, 0x45, 0xc4, 0xae, 0xf5, 0x0f, 0x02, 0xba, - 0xd2, 0x49, 0x03, 0xe2, 0xed, 0x68, 0x56, 0x9f, 0xa3, 0xeb, 0xa2, 0xb9, 0x21, 0x7a, 0x7e, 0x3a, - 0xbd, 0xe0, 0xd0, 0xf1, 0x3e, 0x61, 0x13, 0xc3, 0xf8, 0x03, 0x4d, 0x6e, 0xf8, 0x39, 0x4c, 0x89, - 0x01, 0x4b, 0x47, 0x6e, 0xe8, 0x84, 0xe1, 0x31, 0x77, 0x48, 0x14, 0x41, 0xac, 0x17, 0x8e, 0xdc, - 0xd0, 0x0e, 0x8f, 0x65, 0xca, 0x9d, 0x73, 0x0c, 0x27, 0x70, 0x47, 0xd1, 0x91, 0xa3, 0x5e, 0x0c, - 0x78, 0x8f, 0x9e, 0x3d, 0x72, 0xc3, 0x26, 0x2b, 0x53, 0x78, 0x93, 0x97, 0x60, 0x19, 0xf9, 0x76, - 0x7c, 0xc9, 0x18, 0xa3, 0xb8, 0xd0, 0x45, 0xc6, 0xb8, 0xe3, 0x73, 0xce, 0x62, 0x70, 0xbf, 0x5f, - 0x82, 0xf3, 0xf9, 0xbd, 0x87, 0x6b, 0x88, 0xf5, 0x39, 0xbe, 0x37, 0x15, 0x75, 0x9b, 0x67, 0x10, - 0x1e, 0x81, 0x27, 0x6f, 0xf0, 0x0a, 0xb9, 0x83, 0xb7, 0x09, 0xab, 0xc8, 0x48, 0x5c, 0x41, 0x7a, - 0x7e, 0x18, 0x89, 0xc0, 0x32, 0x74, 0x85, 0x15, 0xf0, 0x43, 0xa7, 0xce, 0xc0, 0x6c, 0x66, 0xca, - 0x63, 0x23, 0x78, 0xd2, 0x67, 0x1f, 0xe6, 0x67, 0xc6, 0x92, 0x80, 0x36, 0x11, 0x48, 0xce, 0xc1, - 0xac, 0x3b, 0x18, 0xb0, 0x4f, 0xf2, 0xa3, 0x62, 0xc6, 0x1d, 0x0c, 0x78, 0x9e, 0x29, 0x9e, 0xd1, - 0xeb, 0x00, 0xdd, 0xc7, 0x84, 0xff, 0x2b, 0x5d, 0x44, 0x20, 0x77, 0x29, 0x0b, 0xd9, 0xe6, 0xc4, - 0x68, 0x25, 0xca, 0x1c, 0xa2, 0x80, 0x3b, 0x88, 0x11, 0x2e, 0x42, 0x59, 0x3a, 0x32, 0xf0, 0xe7, - 0x44, 0x74, 0xce, 0x15, 0x4e, 0x0c, 0x6f, 0xc3, 0x05, 0x91, 0x3e, 0xcc, 0xe1, 0x4d, 0x1a, 0x0c, - 0xc4, 0x7b, 0x5e, 0x1e, 0x40, 0x9a, 0xae, 0x89, 0x62, 0xd6, 0x93, 0xe6, 0x60, 0x10, 0xbf, 0xea, - 0xdd, 0x90, 0x64, 0x8f, 0x7c, 0x1e, 0xe8, 0x8e, 0x3b, 0xf3, 0xe2, 0xe2, 0x00, 0xa4, 0x5c, 0x17, - 0x18, 0x5b, 0x2a, 0x82, 0x5c, 0x26, 0xf1, 0x4a, 0x72, 0xb8, 0xe2, 0x53, 0x88, 0x4f, 0x68, 0xee, - 0xc6, 0x41, 0x43, 0x28, 0x79, 0x07, 0x26, 0xce, 0x45, 0x94, 0xce, 0xcb, 0xf4, 0x1c, 0x2f, 0xe7, - 0x4e, 0xca, 0xf5, 0xe0, 0xd0, 0xc2, 0x42, 0xf2, 0x3e, 0x5c, 0x96, 0x15, 0x74, 0xc3, 0xd0, 0x3f, - 0xec, 0x3b, 0x72, 0x14, 0xd0, 0x8f, 0x04, 0x25, 0xf4, 0x32, 0xbd, 0x28, 0x70, 0x4c, 0x44, 0xa9, - 0x72, 0x0c, 0x7c, 0x0f, 0x2a, 0x66, 0xd3, 0x17, 0x61, 0x45, 0x5c, 0x36, 0x84, 0xa4, 0x82, 0xbd, - 0x2d, 0xf6, 0x51, 0xc7, 0xef, 0xca, 0xdc, 0x65, 0x20, 0x40, 0xb5, 0xae, 0xa4, 0xfc, 0x2f, 0x1a, - 0x9c, 0xcb, 0xbd, 0xad, 0x90, 0x5f, 0x01, 0xfe, 0x40, 0x33, 0x0a, 0x9c, 0xa1, 0xd7, 0xf1, 0x07, - 0x3e, 0x46, 0xbc, 0xe1, 0xda, 0xfc, 0xdb, 0xd3, 0xee, 0x39, 0xf8, 0xd8, 0xb3, 0x1d, 0xd0, 0x98, - 0x88, 0xab, 0x19, 0xf5, 0x61, 0x06, 0xbc, 0xf1, 0x01, 0x9c, 0xcb, 0x45, 0xcd, 0x51, 0xff, 0x7d, - 0x5e, 0x55, 0xff, 0x25, 0xf6, 0xd9, 0x4c, 0xa3, 0x15, 0xb5, 0xa0, 0x68, 0xde, 0x1f, 0xc7, 0xcd, - 0xcb, 0xdc, 0x6b, 0x88, 0x95, 0xdd, 0xd9, 0xf2, 0xae, 0xe6, 0x92, 0x68, 0xf2, 0xe6, 0xf6, 0x01, - 0x9c, 0x13, 0xcb, 0x8b, 0x6f, 0xec, 0x31, 0x3b, 0x5e, 0xd1, 0xcf, 0xe5, 0xb1, 0xe3, 0xeb, 0x6e, - 0x87, 0xe1, 0xc7, 0x5c, 0xcf, 0xba, 0xe3, 0x40, 0xd1, 0x86, 0x5f, 0x2b, 0xc8, 0xcd, 0x2c, 0xa7, - 0x3a, 0x39, 0x0b, 0x57, 0xcb, 0x5b, 0xb8, 0xa7, 0xdf, 0x35, 0x1a, 0x40, 0xd4, 0xed, 0x5a, 0xcc, - 0x7b, 0xee, 0x4b, 0x78, 0x35, 0x9d, 0x29, 0x50, 0xd9, 0xfc, 0xf8, 0x42, 0xa0, 0xab, 0x9d, 0x2c, - 0x88, 0x5d, 0x08, 0xf8, 0x21, 0xc9, 0x3e, 0xc9, 0xcf, 0xef, 0x32, 0x07, 0xd4, 0xba, 0xe4, 0x1a, - 0x2c, 0xf2, 0xdb, 0x68, 0x6a, 0x57, 0x01, 0x84, 0x99, 0x6c, 0x6b, 0x91, 0x7d, 0xa0, 0xc1, 0xb5, - 0xa7, 0xf5, 0x21, 0x79, 0x00, 0xe7, 0xd1, 0xa3, 0x29, 0x0c, 0xe2, 0x61, 0x70, 0x3a, 0x6e, 0xe7, - 0xc8, 0x13, 0xb3, 0xd6, 0xc8, 0x1d, 0x8c, 0xc1, 0xc0, 0xb6, 0x9b, 0xca, 0x38, 0x0c, 0x06, 0x76, - 0x18, 0xc8, 0xdf, 0x15, 0x46, 0x2e, 0xea, 0xd0, 0x85, 0x4b, 0x53, 0x28, 0x95, 0xad, 0x51, 0x53, - 0xb7, 0xc6, 0x57, 0x40, 0x3f, 0xf0, 0xba, 0xec, 0xae, 0xe5, 0x75, 0xb1, 0x6a, 0x1f, 0xdf, 0xc6, - 0x8e, 0x5f, 0xa4, 0xcb, 0x31, 0xdc, 0x0e, 0x83, 0xfb, 0xb7, 0xc5, 0x57, 0x8e, 0xe5, 0xa1, 0xaf, - 0xde, 0xa8, 0xc9, 0x4d, 0x38, 0x9b, 0x89, 0x26, 0x94, 0x84, 0xa7, 0xa0, 0xab, 0xac, 0x28, 0x1d, - 0x7b, 0xee, 0x3a, 0x2c, 0xaa, 0x1b, 0x89, 0x14, 0x33, 0xbb, 0xc9, 0xd6, 0x21, 0x3e, 0x37, 0x92, - 0x8d, 0xca, 0xbd, 0x8c, 0x9f, 0xe6, 0xc2, 0xf7, 0x3a, 0x90, 0xf8, 0xfa, 0x14, 0x6f, 0x14, 0xe2, - 0x83, 0xab, 0xb2, 0x24, 0x5e, 0xe1, 0xe2, 0xb3, 0xff, 0x7a, 0x16, 0xce, 0xe6, 0xdc, 0xe2, 0xc9, - 0xeb, 0xa0, 0xfb, 0xfd, 0xc8, 0x3b, 0x1c, 0x2a, 0xf7, 0x43, 0x7e, 0x85, 0x28, 0xac, 0x6b, 0x74, - 0x45, 0x29, 0x13, 0xea, 0xd9, 0xd9, 0xa1, 0x77, 0x18, 0xab, 0x7a, 0xa9, 0xf8, 0xc5, 0x36, 0x10, - 0x77, 0x28, 0x35, 0x8f, 0xec, 0x4f, 0x52, 0x83, 0x55, 0x4c, 0xe6, 0x12, 0xfa, 0x01, 0xe6, 0x84, - 0x41, 0x79, 0xb0, 0x94, 0xba, 0xeb, 0x63, 0x4d, 0x5a, 0x0a, 0x12, 0x13, 0x08, 0xa9, 0x3e, 0xc8, - 0x40, 0xc8, 0x97, 0x61, 0x43, 0x39, 0x51, 0x9d, 0xcc, 0xea, 0xc3, 0xc7, 0x23, 0xf4, 0x82, 0x1b, - 0x9f, 0xad, 0xd5, 0xd4, 0x3a, 0xdc, 0x02, 0x9e, 0xb5, 0xdb, 0xef, 0x0e, 0x9c, 0xb1, 0xec, 0x3f, - 0xd8, 0x5c, 0x9e, 0x8a, 0x62, 0x83, 0x61, 0xd5, 0xba, 0x83, 0x4c, 0x22, 0x20, 0x6c, 0x75, 0x2b, - 0x77, 0x85, 0xce, 0xe1, 0x0a, 0x7d, 0x41, 0x6d, 0xcc, 0xd8, 0xfa, 0xc4, 0x5e, 0xcc, 0x59, 0xa3, - 0x87, 0xb0, 0x9a, 0x9c, 0x74, 0xf2, 0x80, 0x2e, 0xe3, 0xa2, 0xd9, 0x50, 0x19, 0x4a, 0x09, 0x92, - 0x9f, 0xd8, 0x3c, 0xc2, 0xc6, 0x18, 0xa1, 0x1a, 0x47, 0x66, 0x94, 0x22, 0x08, 0x49, 0x1d, 0xd6, - 0xdc, 0x27, 0xa1, 0xcc, 0x05, 0x1c, 0xc6, 0xdf, 0x9a, 0x1f, 0xff, 0x96, 0xb4, 0x35, 0x72, 0x52, - 0x4a, 0xdc, 0x27, 0xa1, 0x48, 0x11, 0x1c, 0x4a, 0x6e, 0x1f, 0x02, 0xe1, 0x62, 0x47, 0xaa, 0xde, - 0xf0, 0x34, 0x5e, 0x22, 0x91, 0xf0, 0x18, 0xa5, 0x1a, 0x0d, 0x0f, 0x4b, 0xd5, 0x9a, 0xb7, 0xd3, - 0xfa, 0xe1, 0x85, 0x94, 0x71, 0x33, 0xdb, 0xdb, 0xdc, 0xf0, 0xaa, 0xe0, 0xab, 0xf7, 0x5d, 0x05, - 0x8c, 0x57, 0x1c, 0x8c, 0x96, 0x85, 0xf5, 0x38, 0x66, 0x97, 0xd1, 0x45, 0x71, 0xc5, 0x61, 0x60, - 0x56, 0x81, 0xbd, 0xe4, 0xda, 0xf9, 0x1d, 0x0d, 0xf4, 0xec, 0xa7, 0xc8, 0x57, 0x60, 0x96, 0x0b, - 0x1d, 0xe2, 0x04, 0x33, 0xf2, 0xeb, 0xc4, 0x47, 0x9a, 0xcb, 0x1f, 0xbb, 0x67, 0xa8, 0xa0, 0x21, - 0x5f, 0x80, 0x52, 0xe0, 0x77, 0xa5, 0xb1, 0xf6, 0xda, 0x34, 0xda, 0x66, 0xad, 0x5a, 0x41, 0x05, - 0xaf, 0xdf, 0x15, 0xf7, 0xa4, 0xad, 0x32, 0xcc, 0xf2, 0x8e, 0x35, 0x3e, 0x84, 0x4b, 0x53, 0x3e, - 0x48, 0x2c, 0x58, 0xc9, 0x18, 0xb2, 0x4f, 0x69, 0xe3, 0x76, 0x13, 0x1b, 0xf7, 0x50, 0xca, 0xce, - 0x3d, 0xb8, 0x38, 0xb1, 0x82, 0xa4, 0x36, 0x71, 0x07, 0xc1, 0x78, 0x2e, 0xd9, 0x32, 0x75, 0xb2, - 0x66, 0x76, 0x17, 0xf1, 0xb5, 0xdf, 0x2c, 0xc0, 0xd9, 0x9c, 0x49, 0x44, 0x0c, 0x28, 0xc8, 0xbd, - 0x7e, 0xdc, 0x4d, 0x72, 0xf7, 0x0c, 0x2d, 0xf8, 0x5d, 0x72, 0x07, 0x00, 0x73, 0x2e, 0x0f, 0xbd, - 0x43, 0xef, 0x13, 0xa1, 0xd0, 0x40, 0x35, 0x43, 0x02, 0x4d, 0xd1, 0xcc, 0xa3, 0xe9, 0x89, 0x81, - 0xc9, 0x2d, 0x00, 0xef, 0x93, 0x4e, 0x6f, 0xd4, 0xf5, 0xe2, 0xdb, 0x59, 0xce, 0x67, 0x34, 0x3a, - 0x2f, 0xb0, 0x6a, 0x5d, 0xb2, 0x0b, 0x44, 0x92, 0x28, 0x5f, 0x2d, 0x3d, 0xe5, 0xab, 0x1a, 0xd5, - 0x05, 0x55, 0x43, 0x7e, 0x5c, 0x8c, 0xee, 0x3c, 0xcc, 0xf9, 0x7d, 0x2c, 0x61, 0x7f, 0x0a, 0x24, - 0xe3, 0x9f, 0x6b, 0xa2, 0x3f, 0xd2, 0x9b, 0x01, 0x69, 0x83, 0xf0, 0x93, 0x10, 0x1b, 0xc7, 0x8d, - 0xc9, 0x1b, 0x87, 0x6a, 0x7e, 0x16, 0x81, 0x7d, 0x10, 0xa0, 0x1a, 0x59, 0x39, 0xe4, 0x39, 0x0c, - 0xc3, 0x62, 0xf8, 0x3e, 0x80, 0x73, 0xb9, 0x1b, 0x3b, 0xbb, 0x6d, 0xa0, 0xbb, 0x75, 0x72, 0x91, - 0x9e, 0x63, 0xbf, 0xd9, 0x4d, 0xfa, 0x3a, 0x2c, 0x3e, 0xf2, 0xdc, 0xa1, 0x37, 0x14, 0xd7, 0x38, - 0x71, 0x7a, 0x72, 0x98, 0x7a, 0x8b, 0xeb, 0xa6, 0x4f, 0x31, 0x61, 0x59, 0x22, 0x7b, 0x70, 0x96, - 0xef, 0x2e, 0xfe, 0x31, 0xaa, 0x2f, 0x84, 0x35, 0x4a, 0x4b, 0xdd, 0x9d, 0x91, 0x04, 0xef, 0x29, - 0x35, 0xc4, 0xe2, 0xd4, 0x74, 0xf5, 0x30, 0x0b, 0x62, 0xc2, 0xcf, 0xf9, 0x7c, 0x6c, 0xb2, 0x05, - 0x0b, 0x9c, 0x39, 0x57, 0x64, 0x71, 0x37, 0x82, 0xeb, 0x53, 0xbf, 0x50, 0xc1, 0x57, 0x48, 0x61, - 0xfc, 0x37, 0xbb, 0xbc, 0xa1, 0xc7, 0x96, 0x73, 0xac, 0x7a, 0x49, 0xd0, 0x45, 0x04, 0x0a, 0xef, - 0x08, 0xe3, 0x3f, 0x6b, 0xb2, 0xa9, 0x29, 0x15, 0x3a, 0x3b, 0x81, 0x43, 0xaf, 0x2f, 0x3d, 0x45, - 0xe6, 0xa9, 0xf8, 0xf5, 0x8c, 0x52, 0x01, 0x79, 0x07, 0x16, 0x19, 0xdb, 0xc3, 0x51, 0x9f, 0x9f, - 0xcc, 0xc5, 0x54, 0xc0, 0xc1, 0x3d, 0x5e, 0xc4, 0x86, 0x6d, 0xf7, 0x0c, 0x5d, 0x38, 0x4e, 0x7e, - 0x92, 0x9b, 0x30, 0x1f, 0x1e, 0x47, 0x03, 0xf5, 0x3c, 0x97, 0xe6, 0x44, 0x7b, 0xaf, 0xdd, 0x12, - 0x24, 0x65, 0x86, 0x93, 0xe8, 0x77, 0xb6, 0x66, 0xb9, 0x41, 0xd1, 0x78, 0x0d, 0x16, 0x14, 0xde, - 0xac, 0x31, 0xfc, 0xcd, 0xae, 0x6c, 0x0c, 0xff, 0x25, 0x06, 0xfb, 0x11, 0x94, 0x25, 0x4b, 0x42, - 0xa0, 0x74, 0x14, 0x84, 0x52, 0x1e, 0xc2, 0xbf, 0x19, 0x0c, 0x2f, 0x7c, 0xac, 0x91, 0x33, 0x14, - 0xff, 0x46, 0xb1, 0x1b, 0x75, 0xd8, 0x18, 0xa6, 0x1a, 0xfd, 0xb4, 0x63, 0x4d, 0x0b, 0x83, 0xb7, - 0x7b, 0x21, 0xf7, 0xde, 0x96, 0x3a, 0x9f, 0xf8, 0xbe, 0x92, 0xb1, 0x39, 0x4c, 0x12, 0x2f, 0x53, - 0xd2, 0x75, 0x61, 0x5c, 0xba, 0xe6, 0x81, 0xe4, 0x04, 0x25, 0xff, 0x32, 0x20, 0x0c, 0xa5, 0x6b, - 0x45, 0x80, 0x2a, 0xa5, 0x04, 0x28, 0x45, 0x8b, 0x9c, 0x8c, 0x1e, 0x17, 0xce, 0xa5, 0x16, 0x39, - 0x2b, 0xd2, 0x7d, 0x37, 0x9e, 0x21, 0x29, 0xab, 0x07, 0xb9, 0x0d, 0xe7, 0xb8, 0x16, 0x85, 0x67, - 0xdc, 0xca, 0xca, 0x92, 0x67, 0xb1, 0x90, 0x27, 0x38, 0x8c, 0x65, 0xca, 0xa7, 0x6b, 0x49, 0xc9, - 0x9b, 0xb0, 0x16, 0xe7, 0xdb, 0x0e, 0x1f, 0xfb, 0x03, 0x9e, 0x1e, 0xf4, 0x44, 0xe8, 0x37, 0x88, - 0x2c, 0xb3, 0x1f, 0xfb, 0x03, 0x4c, 0x15, 0x2a, 0x7b, 0xf8, 0x0f, 0x0b, 0x52, 0xf7, 0xbe, 0x15, - 0x04, 0x51, 0x18, 0x0d, 0xdd, 0x41, 0xca, 0xae, 0x4b, 0x8e, 0xe1, 0x22, 0x56, 0xe9, 0x36, 0xa6, - 0x18, 0x0b, 0x86, 0xd2, 0x56, 0x11, 0x2f, 0xb0, 0x85, 0xdb, 0x6f, 0xa4, 0xf5, 0x56, 0x26, 0xc3, - 0x36, 0x55, 0x64, 0xb6, 0xae, 0x14, 0xae, 0xbb, 0x67, 0xe8, 0x05, 0xce, 0x73, 0x0c, 0x8b, 0xec, - 0xe6, 0xec, 0x35, 0x59, 0xc3, 0xee, 0x56, 0xb2, 0xf1, 0xa4, 0xb9, 0xaa, 0x5b, 0x12, 0x79, 0x0f, - 0xe6, 0xfd, 0xae, 0x9a, 0xe8, 0x3b, 0x6b, 0x52, 0xac, 0x75, 0x79, 0x82, 0x8f, 0x84, 0x07, 0x5b, - 0x1a, 0xbe, 0x80, 0x6e, 0x2d, 0xa5, 0x24, 0x1c, 0x63, 0x57, 0xaa, 0x79, 0xc7, 0xc9, 0xc8, 0x72, - 0x72, 0xf6, 0xe1, 0x39, 0x87, 0xbb, 0x40, 0x92, 0x62, 0x84, 0x8a, 0x5f, 0xa2, 0xcb, 0x7f, 0x15, - 0x5e, 0x39, 0x6d, 0x4f, 0xb1, 0x7d, 0x63, 0x42, 0xb7, 0xcf, 0xf3, 0xf0, 0xe2, 0xe9, 0xde, 0xbb, - 0x0e, 0x6a, 0x5a, 0x04, 0x5f, 0x4e, 0x14, 0x09, 0xdb, 0x1f, 0xfa, 0xc6, 0x5f, 0x16, 0x61, 0x39, - 0x6d, 0xf9, 0x27, 0xaf, 0x41, 0x49, 0xd9, 0x2e, 0x2f, 0xe4, 0xb8, 0x07, 0xe0, 0x26, 0x89, 0x48, - 0xa7, 0xda, 0x1e, 0xc9, 0x5d, 0x58, 0xc6, 0xb7, 0x08, 0x28, 0xc6, 0x45, 0xbe, 0xb0, 0x6a, 0x9d, - 0xd6, 0x5e, 0xb5, 0xc8, 0x68, 0xd9, 0xf1, 0xc8, 0x0a, 0x15, 0xc3, 0x6e, 0x69, 0xb2, 0x61, 0x57, - 0x34, 0x65, 0x82, 0x61, 0x77, 0x66, 0x8a, 0x61, 0x37, 0xa1, 0x54, 0x0d, 0xbb, 0x68, 0xde, 0x9f, - 0x9b, 0x64, 0xde, 0x4f, 0x68, 0xb8, 0x79, 0x3f, 0x31, 0xcc, 0x96, 0x27, 0x1a, 0x66, 0x13, 0x1a, - 0x61, 0x98, 0x4d, 0x4c, 0xa5, 0xf3, 0x13, 0x4d, 0xa5, 0x0a, 0x11, 0x37, 0x95, 0xbe, 0x24, 0x3a, - 0x76, 0xe8, 0x3e, 0x71, 0xb0, 0xc7, 0xc5, 0xfd, 0x08, 0xbb, 0x8c, 0xba, 0x4f, 0xd0, 0xc9, 0x98, - 0x89, 0x27, 0xc2, 0x33, 0xd9, 0xf8, 0x5e, 0x66, 0x1b, 0x92, 0x63, 0xfe, 0x32, 0x2c, 0xf3, 0xd3, - 0x58, 0x84, 0xad, 0xe7, 0xc7, 0xf1, 0x12, 0x5d, 0x92, 0x50, 0xae, 0x5d, 0xfd, 0x1c, 0xac, 0xc4, - 0x68, 0x42, 0xc1, 0x88, 0x41, 0x10, 0x68, 0x4c, 0x2d, 0x54, 0x8b, 0x2a, 0xbf, 0xa1, 0x08, 0xc9, - 0x97, 0xe2, 0xc7, 0xe3, 0xb5, 0xbd, 0x0e, 0x24, 0x41, 0x8b, 0xdf, 0x69, 0x94, 0x10, 0x75, 0x35, - 0x46, 0x8d, 0x1f, 0x53, 0xfc, 0xae, 0x96, 0xb1, 0x2d, 0xfe, 0xac, 0xaa, 0xff, 0x1a, 0xc4, 0x5f, - 0x77, 0x84, 0x7d, 0x48, 0xb6, 0x40, 0x97, 0x05, 0x2d, 0x01, 0x37, 0x0e, 0xb3, 0x4a, 0xb4, 0x9f, - 0x51, 0xad, 0x8c, 0x3f, 0x2c, 0xa5, 0x4c, 0x1e, 0xf2, 0x33, 0x4c, 0xca, 0x09, 0x03, 0x47, 0x0c, - 0xb1, 0xd8, 0x84, 0xaf, 0x4f, 0x98, 0xa6, 0xc2, 0x33, 0xdd, 0xb6, 0x9b, 0x14, 0xc2, 0x30, 0x90, - 0x8e, 0xea, 0x0e, 0x57, 0x0e, 0x29, 0xb7, 0x3e, 0xc9, 0x8e, 0xef, 0xb8, 0x9b, 0xd3, 0xd9, 0x49, - 0x9d, 0x32, 0x5b, 0xa5, 0xa8, 0x24, 0x8a, 0x7f, 0xc9, 0x0f, 0xec, 0x03, 0x9a, 0x29, 0xc3, 0x34, - 0xf3, 0x62, 0x8e, 0x1a, 0x70, 0x8c, 0x39, 0xf6, 0x12, 0x72, 0x46, 0x85, 0x73, 0xa8, 0xb2, 0xb5, - 0x60, 0x11, 0x0d, 0x0a, 0x92, 0x61, 0x29, 0xc7, 0x91, 0x62, 0xbc, 0xf1, 0x95, 0xda, 0x1e, 0x5d, - 0x60, 0x74, 0x92, 0xcd, 0x11, 0x5c, 0x54, 0xcd, 0x00, 0xe9, 0x4a, 0xce, 0xc8, 0x64, 0x13, 0x53, - 0x7b, 0x20, 0xb1, 0x16, 0x60, 0x55, 0xcf, 0xbb, 0x69, 0x80, 0xfc, 0x52, 0x07, 0x2e, 0x8e, 0x29, - 0xc1, 0xe3, 0x2f, 0x71, 0xc7, 0x9e, 0x57, 0x26, 0x7c, 0x29, 0xa3, 0x1d, 0xf7, 0x86, 0xf4, 0x7c, - 0x98, 0x06, 0x89, 0x8f, 0xe0, 0x4b, 0x90, 0xc9, 0x03, 0x3f, 0x25, 0x41, 0x69, 0x22, 0x46, 0x15, - 0x54, 0x31, 0x4a, 0x35, 0x3d, 0x14, 0xd3, 0xa6, 0x87, 0x6d, 0xb8, 0xc6, 0xf6, 0x3c, 0x31, 0x73, - 0xbc, 0x8f, 0xbd, 0xe1, 0x49, 0xd0, 0xc7, 0xb8, 0x85, 0x83, 0x78, 0xe9, 0x73, 0x5b, 0xc9, 0x65, - 0x86, 0x87, 0xf3, 0xc2, 0x12, 0x58, 0x7b, 0x88, 0xc4, 0xe3, 0x71, 0xfe, 0xb3, 0x22, 0xbc, 0x78, - 0x8a, 0xc9, 0x35, 0xa5, 0xee, 0xbf, 0x90, 0x16, 0xf6, 0x0b, 0x29, 0x95, 0x2c, 0x63, 0x2a, 0x4e, - 0xb0, 0x93, 0x7e, 0x67, 0x82, 0xa8, 0xff, 0x2b, 0xb0, 0xc2, 0x8f, 0x29, 0xfe, 0x14, 0xe6, 0x60, - 0xd4, 0x3b, 0xc5, 0x39, 0x75, 0x49, 0xbe, 0xdb, 0xcf, 0x90, 0xe2, 0xd1, 0x85, 0xbb, 0xb3, 0x1d, - 0xc3, 0x48, 0x1b, 0x16, 0x10, 0xed, 0xc0, 0xf5, 0x7b, 0xa7, 0x7a, 0x40, 0x2e, 0xa3, 0x02, 0xa8, - 0x64, 0xfc, 0x05, 0x1f, 0x03, 0x6c, 0xe3, 0x6f, 0x72, 0x03, 0x56, 0xfa, 0xa3, 0x63, 0x26, 0xc6, - 0xf2, 0x99, 0x2b, 0x3c, 0x8e, 0x67, 0xe8, 0x52, 0x7f, 0x74, 0x6c, 0x0e, 0x06, 0x38, 0x01, 0xd1, - 0x35, 0x79, 0x95, 0xe1, 0xf1, 0x3d, 0x46, 0x62, 0xce, 0x22, 0x26, 0x63, 0xc0, 0x77, 0x19, 0x81, - 0xbb, 0x06, 0xfc, 0xa1, 0x8a, 0x48, 0xf4, 0xca, 0x7f, 0x18, 0xff, 0xa3, 0x20, 0x15, 0xcd, 0x93, - 0x57, 0xe9, 0xcf, 0x87, 0x28, 0x67, 0x88, 0x5e, 0x01, 0x9d, 0x75, 0x7d, 0xb2, 0x05, 0xc6, 0x63, - 0xb4, 0xdc, 0x1f, 0x1d, 0xc7, 0x7d, 0xa7, 0x76, 0xfc, 0xac, 0xda, 0xf1, 0xef, 0x48, 0x45, 0x74, - 0xee, 0x66, 0x36, 0xb9, 0xcb, 0x99, 0x7c, 0x77, 0xe3, 0x74, 0x5b, 0xd6, 0xcf, 0xc7, 0x2d, 0x67, - 0xdc, 0x32, 0x56, 0xd9, 0x99, 0x31, 0xab, 0x6c, 0xce, 0xda, 0x9b, 0xcd, 0x5b, 0x7b, 0x63, 0x36, - 0xe0, 0xb9, 0x1c, 0x1b, 0x70, 0xee, 0x02, 0x2d, 0x3f, 0x65, 0x81, 0xce, 0xab, 0xf3, 0xe4, 0x07, - 0x05, 0xb8, 0xfe, 0xd4, 0x73, 0xe3, 0xe7, 0x23, 0x9d, 0x33, 0xd2, 0xf9, 0xfd, 0xf9, 0x97, 0x05, - 0x29, 0x2f, 0xa7, 0xaf, 0xc1, 0x1f, 0xc0, 0x59, 0x79, 0x0d, 0xe6, 0x72, 0x43, 0xe2, 0x2a, 0xb1, - 0x70, 0xfb, 0xd5, 0xbc, 0x0b, 0x30, 0xa2, 0xe5, 0x5c, 0x52, 0x57, 0xc5, 0xd5, 0x37, 0x29, 0xff, - 0xbf, 0xe7, 0xd2, 0x4b, 0x1e, 0xc2, 0x79, 0x4c, 0x43, 0xd5, 0x51, 0x9d, 0x3c, 0x9c, 0xa1, 0x77, - 0x20, 0x7a, 0xfd, 0xfa, 0xd8, 0xe5, 0xd0, 0xef, 0x28, 0xd5, 0xa1, 0xde, 0xc1, 0xee, 0x19, 0xba, - 0x16, 0xe6, 0xc0, 0x85, 0xaa, 0x29, 0x73, 0xab, 0xfe, 0x57, 0x1a, 0x18, 0x4f, 0xef, 0x35, 0x54, - 0x80, 0x64, 0xbb, 0x7d, 0x9e, 0x2e, 0xb8, 0x4a, 0x1f, 0xbe, 0x08, 0x4b, 0x43, 0xef, 0x60, 0xe8, - 0x85, 0x47, 0x29, 0x2d, 0xe5, 0xa2, 0x00, 0xca, 0xee, 0x91, 0x11, 0xf1, 0x9f, 0xe9, 0x42, 0x2a, - 0x89, 0x62, 0xf7, 0xc9, 0xcb, 0xd3, 0xc6, 0x84, 0xcd, 0x2c, 0xb5, 0x9a, 0xfc, 0x47, 0xec, 0xaa, - 0x53, 0xd0, 0x8b, 0x54, 0xc4, 0xf0, 0x3f, 0xf0, 0x7b, 0x9e, 0xf1, 0x6f, 0x63, 0xd9, 0x2d, 0xaf, - 0x3b, 0xc9, 0x07, 0xca, 0x13, 0xbd, 0xe2, 0x98, 0x58, 0x9a, 0x47, 0x72, 0x1a, 0x75, 0x72, 0xfd, - 0x33, 0x52, 0x27, 0xdf, 0x91, 0x7e, 0xfe, 0xec, 0x54, 0xb9, 0x7f, 0x8b, 0xbc, 0x0a, 0x73, 0xdc, - 0xb5, 0x5f, 0x56, 0x77, 0x25, 0x55, 0xdd, 0xfb, 0xb7, 0xa8, 0x2c, 0x37, 0xbe, 0x13, 0x3b, 0x25, - 0x8d, 0x35, 0xe2, 0xfe, 0x2d, 0xf2, 0xce, 0xe9, 0x9e, 0xdc, 0x95, 0xe5, 0x93, 0xbb, 0xf8, 0xb9, - 0xdd, 0x17, 0x53, 0xcf, 0xed, 0x5e, 0x9a, 0xde, 0x5b, 0xc2, 0xdf, 0x8d, 0xc7, 0x45, 0x8f, 0x83, - 0xdb, 0x1a, 0xdf, 0x2a, 0xc2, 0x0b, 0x53, 0x29, 0xc8, 0x65, 0x28, 0x9b, 0xad, 0x5a, 0x3b, 0x19, - 0x65, 0xb6, 0x8a, 0x24, 0x84, 0xec, 0xc0, 0xfc, 0x96, 0x1b, 0xfa, 0x1d, 0x36, 0xa5, 0x73, 0x3d, - 0x1f, 0xc6, 0xd8, 0xc6, 0xe8, 0xbb, 0x67, 0x68, 0x42, 0x4b, 0x1c, 0x58, 0xc5, 0x75, 0x91, 0x4a, - 0x5b, 0x5b, 0xcc, 0x51, 0xba, 0x8d, 0x31, 0x1c, 0x23, 0x63, 0x3b, 0xcf, 0x18, 0x90, 0x3c, 0x02, - 0x62, 0xdb, 0xbb, 0x15, 0x6f, 0x18, 0x09, 0x35, 0x54, 0xe4, 0xc7, 0xef, 0xb7, 0xde, 0x7c, 0x4a, - 0xdf, 0x8d, 0xd1, 0xed, 0x9e, 0xa1, 0x39, 0xdc, 0xc8, 0x75, 0x50, 0xf3, 0x2b, 0xa3, 0x14, 0xb4, - 0xb8, 0x7b, 0x86, 0xc2, 0x20, 0xce, 0xb3, 0x9c, 0xbf, 0x37, 0xfc, 0xaa, 0x14, 0x3d, 0x27, 0xf7, - 0xd6, 0x33, 0x24, 0xa7, 0x78, 0x05, 0xca, 0x2d, 0xe9, 0x16, 0xab, 0x3c, 0x98, 0x95, 0x2e, 0xb0, - 0x34, 0x2e, 0x15, 0x33, 0xfb, 0x77, 0x34, 0xa9, 0xa6, 0x7b, 0x7a, 0xdf, 0x2a, 0x49, 0x88, 0xbb, - 0xd3, 0x93, 0x10, 0x77, 0x7f, 0xca, 0x24, 0xc4, 0xa2, 0x52, 0x01, 0xbc, 0x7a, 0xea, 0xd1, 0x20, - 0x5f, 0x01, 0x1d, 0x93, 0xb4, 0xba, 0xca, 0xc8, 0xf2, 0x45, 0xb9, 0x1a, 0x67, 0x2e, 0xda, 0x15, - 0xa9, 0xb1, 0xe9, 0x4a, 0x27, 0x4d, 0x2d, 0x3e, 0xf8, 0x47, 0x22, 0x6f, 0x55, 0xad, 0xdb, 0xca, - 0x98, 0xde, 0x9f, 0xf7, 0xd5, 0xb5, 0x95, 0x5a, 0xa7, 0x2f, 0x2a, 0x89, 0xf5, 0xc7, 0xbf, 0x35, - 0xf9, 0xf1, 0xb5, 0xb2, 0x68, 0xff, 0x51, 0x11, 0x2e, 0x4f, 0x23, 0x27, 0x26, 0xe8, 0x16, 0x0f, - 0xcc, 0x28, 0xde, 0xbb, 0x05, 0x43, 0x35, 0x8f, 0x22, 0x0f, 0xda, 0xe8, 0x74, 0xe3, 0x42, 0x3a, - 0x86, 0xce, 0xc6, 0x99, 0xc3, 0xe2, 0x27, 0xc5, 0x38, 0xce, 0x82, 0x94, 0x8d, 0xb3, 0x2c, 0x26, - 0x2f, 0xc2, 0xac, 0x59, 0xb1, 0x93, 0x84, 0xd1, 0xf8, 0xf6, 0xcf, 0xed, 0x84, 0xf8, 0xaa, 0x4c, - 0x14, 0x91, 0x5f, 0x1e, 0xcf, 0x91, 0x2e, 0x32, 0x45, 0x5f, 0x52, 0x3a, 0x64, 0x2c, 0xa5, 0x1c, - 0xd6, 0x37, 0x49, 0x81, 0x26, 0xb2, 0x0a, 0xd1, 0xf1, 0x7c, 0xeb, 0x06, 0xcc, 0xb6, 0x86, 0x5e, - 0xe8, 0x45, 0xea, 0xbb, 0xbc, 0x01, 0x42, 0xa8, 0x28, 0x11, 0xaf, 0xe6, 0xdc, 0x13, 0x1e, 0x24, - 0x6d, 0x56, 0x0d, 0x86, 0x89, 0xcf, 0xec, 0x18, 0x98, 0x2a, 0x28, 0x8c, 0xa0, 0xee, 0x8e, 0xfa, - 0x9d, 0xa3, 0x7d, 0x5a, 0x17, 0x62, 0x2d, 0x27, 0xe8, 0x21, 0x94, 0x35, 0x30, 0xa4, 0x0a, 0x8a, - 0xf1, 0x1b, 0x1a, 0xac, 0xe5, 0xb5, 0x83, 0x5c, 0x86, 0x52, 0x3f, 0x37, 0x1d, 0x7c, 0x9f, 0xc7, - 0x76, 0x5a, 0x40, 0x0b, 0xed, 0x41, 0x30, 0x3c, 0x76, 0x23, 0xf5, 0xf5, 0xa2, 0x02, 0xa6, 0x68, - 0x51, 0xde, 0xc6, 0xbf, 0xc9, 0x55, 0x79, 0x5a, 0x15, 0xc7, 0x12, 0xc8, 0xe3, 0x7f, 0x86, 0x09, - 0x50, 0xeb, 0xb6, 0x9a, 0x03, 0x9e, 0xd2, 0xec, 0x2d, 0x28, 0xb1, 0x6a, 0x65, 0x66, 0x2f, 0x9b, - 0x3f, 0xe6, 0x5e, 0x5d, 0x20, 0xf1, 0x5a, 0x85, 0xee, 0x71, 0x8f, 0x22, 0xb2, 0xf1, 0x00, 0x96, - 0xd3, 0x18, 0xc4, 0x4a, 0x67, 0xb5, 0x58, 0xb8, 0xad, 0x0b, 0x4e, 0x5b, 0x41, 0xc0, 0x5f, 0xd0, - 0x6f, 0x5d, 0xfc, 0xe1, 0xa7, 0x57, 0x81, 0xfd, 0xe4, 0x34, 0x79, 0x59, 0x2f, 0x8c, 0xdf, 0x2a, - 0xc0, 0x5a, 0x12, 0xb4, 0x4b, 0xae, 0xa1, 0xbf, 0xb5, 0x11, 0x64, 0xcc, 0x54, 0x84, 0x13, 0x29, - 0x84, 0x8e, 0x37, 0x70, 0x4a, 0x60, 0x85, 0x1d, 0x58, 0x9f, 0x84, 0x4f, 0x5e, 0x83, 0x79, 0x8c, - 0x1d, 0x3b, 0x70, 0x3b, 0x9e, 0xba, 0xe5, 0xf6, 0x25, 0x90, 0x26, 0xe5, 0xc6, 0x0f, 0x34, 0xd8, - 0x10, 0xef, 0xbe, 0xf7, 0x5c, 0xbf, 0x8f, 0x06, 0xc1, 0x8e, 0xf7, 0xd9, 0x44, 0x40, 0xda, 0x49, - 0xed, 0x63, 0x2f, 0xa7, 0x9f, 0xf7, 0x8f, 0x7d, 0x6d, 0x72, 0x6b, 0xc9, 0xab, 0x18, 0x0f, 0x59, - 0xf8, 0x16, 0x96, 0x78, 0xc4, 0xb9, 0x3e, 0x03, 0xa8, 0x11, 0xe7, 0x10, 0xc3, 0xf8, 0xff, 0xe1, - 0xca, 0xf4, 0x0f, 0x90, 0xaf, 0xc3, 0x12, 0x66, 0x1b, 0xde, 0x1f, 0x1c, 0x0e, 0xdd, 0xae, 0x27, - 0x95, 0xc4, 0xd2, 0x96, 0xa1, 0x96, 0xf1, 0xf0, 0xce, 0x22, 0x02, 0xda, 0x21, 0xe6, 0x31, 0x16, - 0x44, 0xa9, 0xe0, 0x0a, 0x2a, 0x37, 0xe3, 0x9b, 0x1a, 0x90, 0x71, 0x1e, 0xe4, 0x0b, 0xb0, 0xb8, - 0xdf, 0xae, 0xd8, 0x91, 0x3b, 0x8c, 0x76, 0x83, 0xd1, 0x50, 0xc4, 0x56, 0xe6, 0x01, 0xb1, 0xa2, - 0x8e, 0xc3, 0x4d, 0xbf, 0x47, 0xc1, 0x68, 0x48, 0x53, 0x78, 0x98, 0xa7, 0xd6, 0xf3, 0x1e, 0x77, - 0xdd, 0x93, 0x74, 0x9e, 0x5a, 0x01, 0x4b, 0xe5, 0xa9, 0x15, 0x30, 0xe3, 0xbb, 0x1a, 0x5c, 0x92, - 0x2f, 0x77, 0xba, 0x39, 0x75, 0xa9, 0x60, 0xd8, 0xc7, 0xa1, 0xcc, 0x15, 0x32, 0x4d, 0xd0, 0x5f, - 0x95, 0x91, 0x51, 0xb1, 0x82, 0x28, 0xf1, 0x73, 0x5a, 0xf2, 0x0b, 0x50, 0xb2, 0xa3, 0x60, 0x70, - 0x8a, 0xd0, 0xa8, 0x7a, 0x3c, 0xa2, 0x51, 0x30, 0x40, 0x16, 0x48, 0x69, 0x78, 0xb0, 0xa6, 0x56, - 0x4e, 0xd6, 0x98, 0xec, 0xc1, 0x9c, 0x88, 0xab, 0x9d, 0xf1, 0xc6, 0x9c, 0xd2, 0xa6, 0xad, 0x15, - 0x19, 0x7f, 0x55, 0x64, 0xb5, 0xa0, 0x92, 0x87, 0xf1, 0xf7, 0x35, 0x58, 0x60, 0xa2, 0x0e, 0x6a, - 0x0c, 0x9e, 0x77, 0x4a, 0xa7, 0x45, 0x68, 0xe9, 0x5c, 0x1c, 0xb3, 0x3f, 0xd5, 0x69, 0xfc, 0x36, - 0xac, 0x64, 0x08, 0x88, 0x81, 0x91, 0xf7, 0x7a, 0x7e, 0xc7, 0xe5, 0x69, 0x2f, 0xb9, 0x63, 0x6e, - 0x0a, 0x66, 0xfc, 0x5d, 0x0d, 0xd6, 0x9a, 0x8f, 0x23, 0x97, 0x7b, 0x68, 0xd0, 0x51, 0x4f, 0xae, - 0x77, 0x26, 0xbe, 0xc9, 0x27, 0x60, 0x3c, 0x2a, 0x18, 0x17, 0xdf, 0x04, 0x8c, 0xc6, 0xa5, 0x64, - 0x17, 0xca, 0xe2, 0x7c, 0x09, 0x45, 0x0e, 0x88, 0x2b, 0x8a, 0x3a, 0x23, 0x61, 0x2c, 0x90, 0x58, - 0x4b, 0x70, 0x0b, 0x13, 0x34, 0x34, 0xa6, 0x36, 0xfe, 0x4a, 0x83, 0x0b, 0x13, 0x68, 0xc8, 0xbb, - 0x30, 0x83, 0x11, 0x4b, 0xc4, 0xe8, 0x5d, 0x9e, 0xf0, 0x89, 0xa8, 0x73, 0x74, 0xff, 0x16, 0x3f, - 0x88, 0x8e, 0xd9, 0x0f, 0xca, 0xa9, 0xc8, 0x07, 0x30, 0x6f, 0x76, 0xbb, 0xe2, 0x62, 0x57, 0x48, - 0x5d, 0xec, 0x26, 0x7c, 0xf1, 0x66, 0x8c, 0xcf, 0x2f, 0x76, 0xfc, 0xed, 0x7c, 0xb7, 0xeb, 0x88, - 0x68, 0x2c, 0x09, 0xbf, 0x8d, 0xaf, 0xc0, 0x72, 0x1a, 0xf9, 0x99, 0x02, 0x48, 0x7c, 0x47, 0x03, - 0x3d, 0x5d, 0x87, 0x9f, 0x4d, 0xe4, 0xd8, 0xbc, 0x61, 0x7e, 0xca, 0xa4, 0xfa, 0x07, 0x05, 0x38, - 0x97, 0xdb, 0xc3, 0xe4, 0x75, 0x98, 0x35, 0x07, 0x83, 0x5a, 0x55, 0xcc, 0x2a, 0x21, 0x21, 0xa1, - 0x65, 0x23, 0x75, 0xef, 0xe5, 0x48, 0xe4, 0x2d, 0x28, 0x73, 0x47, 0xa0, 0xaa, 0xdc, 0x70, 0x30, - 0x14, 0xa6, 0xf0, 0x52, 0x4a, 0x67, 0x63, 0x90, 0x88, 0x64, 0x1b, 0x96, 0x45, 0x10, 0x49, 0xf4, - 0x0a, 0x8b, 0xb3, 0x8e, 0xa1, 0x23, 0x9d, 0x34, 0x97, 0x70, 0x7f, 0xb2, 0xd4, 0xde, 0x99, 0xa1, - 0x22, 0x75, 0xd0, 0x91, 0xa7, 0xca, 0x89, 0xa7, 0x84, 0x50, 0x1c, 0x31, 0x27, 0xf0, 0x1a, 0xa3, - 0x8c, 0x87, 0x8b, 0x3f, 0x86, 0x38, 0xf6, 0xfa, 0xd1, 0xcf, 0x6e, 0xb8, 0x92, 0x6f, 0x9c, 0x6a, - 0xb8, 0x7e, 0xaf, 0xc4, 0x17, 0x73, 0x96, 0x8c, 0x49, 0x34, 0x4a, 0x92, 0x21, 0x94, 0x68, 0xd8, - 0x8d, 0x4d, 0x84, 0x49, 0xac, 0xc2, 0x1c, 0x0f, 0x5f, 0x29, 0x57, 0xc6, 0x0b, 0xb9, 0x55, 0xe0, - 0x38, 0xf7, 0x6f, 0x71, 0xf1, 0x85, 0x87, 0x4e, 0x09, 0xa9, 0x24, 0x25, 0xf7, 0x61, 0xa1, 0xd2, - 0xf3, 0xdc, 0xfe, 0x68, 0xd0, 0x3e, 0x9d, 0xff, 0xc1, 0xba, 0x68, 0xcb, 0x62, 0x87, 0x93, 0xa1, - 0xdf, 0x02, 0xee, 0xe4, 0x2a, 0x23, 0xd2, 0x8e, 0xa3, 0x29, 0x94, 0x50, 0x57, 0xfa, 0xe6, 0x94, - 0xfe, 0xc9, 0x02, 0x91, 0x2e, 0x1d, 0x2a, 0x44, 0x84, 0x5b, 0x70, 0x60, 0xb9, 0xee, 0x86, 0x51, - 0x7b, 0xe8, 0xf6, 0x43, 0x0c, 0xa5, 0x7f, 0x8a, 0xb0, 0xc0, 0x97, 0x44, 0x85, 0xb9, 0x0e, 0x35, - 0x8a, 0x49, 0xb9, 0x0e, 0x35, 0xcd, 0x8e, 0xc9, 0x4b, 0xdb, 0x7e, 0xdf, 0xed, 0xf9, 0xdf, 0x90, - 0x41, 0x67, 0xb8, 0xbc, 0x74, 0x20, 0x81, 0x34, 0x29, 0x37, 0x7e, 0x69, 0x6c, 0xdc, 0x78, 0x2d, - 0x17, 0x60, 0x4e, 0x84, 0x24, 0xe3, 0x21, 0xba, 0x5a, 0x56, 0xa3, 0x5a, 0x6b, 0xec, 0xe8, 0x1a, - 0x59, 0x06, 0x68, 0xd1, 0x66, 0xc5, 0xb2, 0x6d, 0xf6, 0xbb, 0xc0, 0x7e, 0x8b, 0xf8, 0x5d, 0xdb, - 0xfb, 0x75, 0xbd, 0xa8, 0x84, 0xf0, 0x2a, 0x19, 0xdf, 0xd7, 0xe0, 0x7c, 0xfe, 0x50, 0x92, 0x36, - 0x60, 0x10, 0x37, 0xe1, 0x89, 0xf2, 0x85, 0xa9, 0xe3, 0x9e, 0x0b, 0xce, 0x06, 0x83, 0x8b, 0x78, - 0x90, 0xb1, 0x82, 0x34, 0x70, 0xf2, 0xa8, 0x25, 0x7e, 0x97, 0x16, 0xfc, 0xae, 0x51, 0x81, 0xf5, - 0x49, 0x3c, 0xd2, 0x4d, 0x5d, 0x81, 0x05, 0xb3, 0xd5, 0xaa, 0xd7, 0x2a, 0x66, 0xbb, 0xd6, 0x6c, - 0xe8, 0x1a, 0x99, 0x87, 0x99, 0x1d, 0xda, 0xdc, 0x6f, 0xe9, 0x05, 0xe3, 0x4f, 0x35, 0x58, 0xaa, - 0x25, 0x9e, 0xb2, 0xcf, 0xbb, 0xf8, 0xbe, 0x94, 0x5a, 0x7c, 0xeb, 0x71, 0xb8, 0xc3, 0xf8, 0x03, - 0x53, 0x24, 0xc8, 0xad, 0x38, 0x26, 0x4d, 0x31, 0xe5, 0x51, 0xa2, 0x52, 0xcb, 0x68, 0x1f, 0x71, - 0xa2, 0xb4, 0x74, 0xcc, 0x1a, 0x65, 0xf5, 0xfe, 0x8b, 0x22, 0xac, 0x8e, 0x7d, 0x97, 0xd8, 0x30, - 0x67, 0x3e, 0xb0, 0x9b, 0xb5, 0x6a, 0x45, 0xb4, 0xee, 0x6a, 0xe2, 0x5d, 0x89, 0x79, 0x7f, 0xc7, - 0x6a, 0xca, 0xc3, 0x0c, 0x3d, 0x09, 0x9d, 0xc0, 0xef, 0x76, 0x52, 0xee, 0xbd, 0x92, 0x13, 0x9e, - 0x86, 0xdf, 0x18, 0x0d, 0xd1, 0x63, 0x59, 0xb4, 0x3c, 0x76, 0xda, 0x94, 0xf0, 0x71, 0xc6, 0xe8, - 0xc3, 0xeb, 0xb2, 0xf2, 0x71, 0xd6, 0x09, 0x3f, 0xd2, 0x80, 0xd9, 0x1d, 0x3f, 0xda, 0x1d, 0x3d, - 0x12, 0xbd, 0x72, 0x25, 0xc9, 0x02, 0xbb, 0x3b, 0x7a, 0x34, 0xce, 0x16, 0x35, 0xa6, 0x3c, 0xc4, - 0x40, 0x8a, 0xa5, 0xe0, 0x42, 0xee, 0xc1, 0x8c, 0xf9, 0xc0, 0xa6, 0xa6, 0x58, 0xa1, 0x8a, 0xff, - 0x2a, 0x35, 0x27, 0x70, 0x63, 0xad, 0x1f, 0xba, 0x29, 0x6e, 0x9c, 0x47, 0x36, 0xcc, 0x4a, 0xe9, - 0x99, 0xc2, 0xac, 0x6c, 0x2d, 0xc1, 0x82, 0xb8, 0xd4, 0xe1, 0x7d, 0xe9, 0x13, 0x38, 0x9b, 0x33, - 0xd4, 0xc4, 0x45, 0x2f, 0x79, 0xb4, 0xba, 0x9b, 0xfd, 0x93, 0x27, 0x47, 0xde, 0xd0, 0x1b, 0x1f, - 0xbb, 0x74, 0xdd, 0xe5, 0x2c, 0xc9, 0xad, 0x3d, 0x1d, 0x63, 0x67, 0xfc, 0xb1, 0x06, 0xeb, 0x93, - 0x26, 0x00, 0xbb, 0xa1, 0xa6, 0x03, 0xb9, 0x9d, 0x8f, 0xb3, 0x1d, 0xa6, 0xbd, 0xdb, 0x25, 0x1a, - 0x79, 0x1f, 0x16, 0xb8, 0x07, 0xa4, 0xfd, 0xd6, 0x3e, 0xad, 0x89, 0x95, 0xfb, 0xc2, 0x4f, 0x3e, - 0xbd, 0x7a, 0x41, 0x38, 0x4d, 0x86, 0x6f, 0x39, 0xa3, 0xa1, 0x9f, 0x90, 0xae, 0x6b, 0x54, 0xa5, - 0x60, 0x17, 0x0a, 0x77, 0xd4, 0xf5, 0x3d, 0x79, 0x9d, 0x92, 0xc1, 0xae, 0x04, 0x4c, 0x3d, 0xde, - 0x25, 0xcc, 0xf8, 0xb6, 0x06, 0x1b, 0x93, 0x67, 0x1b, 0x13, 0x19, 0xda, 0xdc, 0x91, 0x54, 0x86, - 0x9b, 0x42, 0x91, 0x21, 0xf6, 0x36, 0x55, 0x79, 0x4a, 0x44, 0x46, 0x24, 0x14, 0x7f, 0x52, 0x5f, - 0x84, 0x44, 0xb1, 0x5e, 0x50, 0x25, 0x92, 0x88, 0xc6, 0x43, 0xb8, 0x30, 0x61, 0x6e, 0x92, 0xf7, - 0x72, 0x73, 0xa8, 0x62, 0x38, 0x01, 0x35, 0x5e, 0x44, 0x2a, 0x19, 0xb7, 0x02, 0x37, 0xfe, 0x13, - 0x77, 0x9d, 0xce, 0x99, 0xa8, 0x4c, 0xba, 0xc1, 0x9c, 0x9d, 0x66, 0xbf, 0x73, 0x14, 0x0c, 0x93, - 0xc1, 0x42, 0xe9, 0x26, 0x62, 0x25, 0x8e, 0x8b, 0x45, 0x99, 0x41, 0xcb, 0x50, 0x91, 0x00, 0x56, - 0x5b, 0xc3, 0xe0, 0xc0, 0xe7, 0x6f, 0x4f, 0xf9, 0xa5, 0x54, 0xac, 0xe9, 0x57, 0x94, 0xe9, 0xa6, - 0x4e, 0x9f, 0x31, 0xfc, 0x38, 0x37, 0x16, 0x03, 0x73, 0xdf, 0x9c, 0x0e, 0x16, 0xd0, 0x71, 0xde, - 0xc6, 0x0f, 0x0b, 0x70, 0xfd, 0xa9, 0x1c, 0x4f, 0x9b, 0x7a, 0xf4, 0x0d, 0x00, 0x41, 0xcb, 0x7a, - 0x40, 0x51, 0x39, 0xc9, 0xca, 0xb8, 0xc3, 0x3e, 0x55, 0x50, 0xc8, 0x63, 0x78, 0x41, 0xfe, 0xea, - 0x74, 0xbc, 0x41, 0x14, 0xb2, 0x7a, 0x88, 0x70, 0xd2, 0x71, 0x20, 0xad, 0xf2, 0xd6, 0xcb, 0x3f, - 0xf9, 0xf4, 0xea, 0xf5, 0x98, 0x07, 0xc7, 0xe4, 0x0f, 0x3c, 0x64, 0x64, 0x6a, 0x54, 0x7c, 0x4d, - 0xe7, 0x45, 0x6e, 0x24, 0x2b, 0xa9, 0x94, 0xa8, 0xb0, 0xe5, 0x4a, 0x4a, 0xd6, 0xcf, 0x2e, 0x10, - 0xc1, 0x88, 0x91, 0x6d, 0xab, 0xb6, 0x6c, 0xbe, 0x6b, 0xca, 0x9a, 0x70, 0x45, 0x1a, 0x2f, 0xa7, - 0x39, 0x34, 0xc6, 0xef, 0xf2, 0x85, 0x9d, 0xbb, 0x3b, 0x90, 0x27, 0xb0, 0xc2, 0xa4, 0x0c, 0xa5, - 0xb3, 0xc5, 0xbe, 0x72, 0xfb, 0xe9, 0x03, 0x5d, 0x8b, 0x44, 0xbc, 0x15, 0x7b, 0x74, 0x7c, 0xec, - 0x0e, 0x4f, 0xb6, 0x2e, 0xca, 0x1c, 0x9a, 0x28, 0xcd, 0xa8, 0x63, 0x4f, 0xb3, 0x5f, 0x31, 0x7e, - 0x5c, 0x80, 0xd7, 0x9e, 0x81, 0x37, 0x69, 0xc1, 0x3c, 0xde, 0xe7, 0x51, 0x12, 0x7c, 0xba, 0x3e, - 0xe0, 0xbc, 0x38, 0x1b, 0x45, 0xbc, 0x95, 0x58, 0x0e, 0x4c, 0x98, 0x90, 0xbb, 0x6c, 0x3a, 0x75, - 0x91, 0xdf, 0xd3, 0x75, 0x03, 0x6b, 0x52, 0x4d, 0xe6, 0xf5, 0xbb, 0x09, 0x37, 0xc9, 0x40, 0x09, - 0x25, 0x57, 0x9c, 0x18, 0x4a, 0xee, 0x6d, 0x58, 0xb4, 0x14, 0x07, 0x5b, 0x31, 0xfc, 0x68, 0x35, - 0x48, 0x79, 0xe3, 0xd2, 0x14, 0x1a, 0xf9, 0x32, 0x2c, 0x73, 0xef, 0x01, 0xd1, 0x3b, 0xdc, 0xb7, - 0x6d, 0x46, 0xe4, 0xbb, 0xc0, 0x12, 0xd9, 0xd5, 0x21, 0xcd, 0xa0, 0xb2, 0x85, 0x75, 0x9e, 0x49, - 0x25, 0x3d, 0x2f, 0x0c, 0xcd, 0x51, 0x74, 0xc4, 0x4e, 0x1d, 0x7e, 0x4f, 0x27, 0xef, 0xc0, 0xec, - 0xd1, 0xb3, 0x59, 0xe7, 0x38, 0x3a, 0x21, 0x80, 0x92, 0xbe, 0x8c, 0x78, 0xc1, 0xfe, 0x26, 0x5f, - 0x84, 0x19, 0x54, 0x32, 0x0b, 0x81, 0x5a, 0x2a, 0x42, 0xf2, 0x3f, 0x8d, 0x2a, 0x68, 0xca, 0x09, - 0xd8, 0x6a, 0x4d, 0x92, 0x83, 0x8a, 0xf3, 0x58, 0x2a, 0x5f, 0xe3, 0xfc, 0xa0, 0x74, 0xfe, 0xf8, - 0xc0, 0x15, 0x19, 0x37, 0x37, 0x61, 0x55, 0xee, 0xbd, 0x03, 0x99, 0x3b, 0x42, 0xf8, 0xdd, 0xac, - 0x88, 0xa8, 0x3c, 0x03, 0x99, 0x3f, 0xe2, 0x25, 0x58, 0x0e, 0xc3, 0x23, 0x47, 0xc4, 0x82, 0x7b, - 0x2c, 0xd3, 0x52, 0xd1, 0xc5, 0x30, 0x3c, 0xe2, 0x41, 0xe1, 0xee, 0x79, 0x27, 0x0c, 0x0b, 0xdf, - 0x32, 0x24, 0x58, 0x65, 0x8e, 0x15, 0xf5, 0xc2, 0x18, 0x4b, 0x84, 0x31, 0x84, 0x04, 0xcb, 0xf8, - 0xaf, 0x05, 0x98, 0x7f, 0xc0, 0x2e, 0xaf, 0xa8, 0x92, 0x9d, 0xae, 0xe2, 0xbd, 0x0d, 0x0b, 0xf5, - 0xc0, 0x15, 0x26, 0x7a, 0x11, 0x72, 0x81, 0x3f, 0x7e, 0xea, 0x05, 0xae, 0xb4, 0xf6, 0x87, 0x54, - 0x45, 0x7a, 0x4a, 0x1c, 0xbf, 0xbb, 0x30, 0xcb, 0x57, 0xb8, 0xb0, 0x36, 0x48, 0xf5, 0x45, 0x5c, - 0xa3, 0x9b, 0xbc, 0x58, 0xb1, 0x21, 0xf3, 0x5d, 0x42, 0xbd, 0x4b, 0x8b, 0x87, 0x4e, 0x8a, 0x02, - 0x7a, 0xe6, 0x74, 0x0a, 0x68, 0x25, 0x07, 0xc0, 0xec, 0x69, 0x72, 0x00, 0x6c, 0xdc, 0x81, 0x05, - 0xa5, 0x3e, 0xcf, 0xa4, 0xcd, 0xf8, 0xb5, 0x02, 0x2c, 0x61, 0xab, 0xe2, 0x5d, 0xeb, 0x6f, 0xa7, - 0x3a, 0xfd, 0x4b, 0x29, 0x75, 0xfa, 0xba, 0x3a, 0x5e, 0xc2, 0xe9, 0x67, 0xb2, 0x1e, 0xfd, 0x2e, - 0xac, 0x8e, 0x21, 0x92, 0xb7, 0x61, 0x86, 0x55, 0x5f, 0xaa, 0x1f, 0xf5, 0xec, 0x0c, 0x48, 0xf2, - 0x45, 0xb1, 0x86, 0x87, 0x94, 0x63, 0x1b, 0xff, 0x5d, 0x83, 0x45, 0x91, 0x8b, 0xb6, 0x7f, 0x10, - 0x3c, 0xb5, 0x3b, 0x6f, 0x64, 0xbb, 0x93, 0x47, 0xa5, 0x15, 0xdd, 0xf9, 0xbf, 0xbb, 0x13, 0xef, - 0xa4, 0x3a, 0xf1, 0x42, 0x9c, 0x3d, 0x42, 0x36, 0x67, 0x4a, 0x1f, 0x7e, 0x0f, 0xf3, 0x29, 0xa5, - 0x11, 0xc9, 0x2f, 0xc3, 0x7c, 0xc3, 0x7b, 0x92, 0xd2, 0xe2, 0xdd, 0x98, 0xc0, 0xf4, 0x66, 0x8c, - 0xc8, 0xd7, 0x14, 0x7f, 0x80, 0xe8, 0x3d, 0x71, 0xc6, 0x7c, 0x33, 0x12, 0x96, 0x1b, 0x5f, 0x81, - 0xe5, 0x34, 0xd9, 0xb3, 0x4c, 0x7d, 0x11, 0xa4, 0x0a, 0x03, 0x2d, 0xff, 0x46, 0x11, 0x20, 0x89, - 0xef, 0xc3, 0x16, 0x60, 0xca, 0x1d, 0x4c, 0x1a, 0x40, 0x11, 0xa4, 0xce, 0x71, 0xe9, 0x25, 0x76, - 0x43, 0x18, 0xea, 0x0a, 0x93, 0xb3, 0x7b, 0xf4, 0x65, 0x8c, 0x32, 0xee, 0x49, 0xdd, 0x73, 0xf9, - 0xdb, 0xa3, 0xe2, 0xd6, 0x4b, 0x98, 0xcc, 0x29, 0x86, 0xa6, 0x52, 0x2f, 0x94, 0xab, 0x23, 0x91, - 0x44, 0x0e, 0x23, 0xba, 0x54, 0x19, 0xc2, 0x58, 0xcc, 0xac, 0xd2, 0xb3, 0xc5, 0xcc, 0x6a, 0xc1, - 0xbc, 0xdf, 0xff, 0xd8, 0xeb, 0x47, 0xc1, 0xf0, 0x04, 0xad, 0x93, 0x89, 0xd9, 0x83, 0x75, 0x41, - 0x4d, 0x96, 0xf1, 0x71, 0x40, 0x49, 0x33, 0xc6, 0x57, 0x87, 0x21, 0x06, 0xc6, 0x9e, 0x3b, 0x33, - 0xfa, 0x2c, 0x0f, 0xb5, 0x73, 0xb7, 0x54, 0x2e, 0xeb, 0xf3, 0x77, 0x4b, 0xe5, 0x79, 0x1d, 0xa8, - 0xe2, 0x6c, 0x10, 0x3b, 0x13, 0x28, 0x96, 0xff, 0xb4, 0x55, 0xdf, 0xf8, 0xeb, 0x02, 0x90, 0xf1, - 0x6a, 0x90, 0x2f, 0xc1, 0x02, 0xdf, 0x60, 0x9d, 0x61, 0xf8, 0x91, 0x78, 0x80, 0xc9, 0x5f, 0x4d, - 0x2b, 0x60, 0x35, 0x5c, 0x35, 0x07, 0xd3, 0xf0, 0xa3, 0x1e, 0xf9, 0x3a, 0x9c, 0xc5, 0xee, 0x1d, - 0x78, 0x43, 0x3f, 0xe8, 0x3a, 0x98, 0x5b, 0xc8, 0xed, 0xe1, 0x58, 0x15, 0xb7, 0x5e, 0xff, 0xc9, - 0xa7, 0x57, 0x5f, 0xc8, 0x29, 0x9e, 0x30, 0x0c, 0x18, 0x21, 0xa7, 0x85, 0x98, 0x2d, 0x8e, 0x48, - 0xda, 0xa0, 0xab, 0xf4, 0x07, 0xa3, 0x5e, 0x4f, 0x8c, 0xec, 0x26, 0xbb, 0x1a, 0x64, 0xcb, 0x26, - 0x30, 0x5e, 0x4e, 0x18, 0x6f, 0x8f, 0x7a, 0x3d, 0xf2, 0x0e, 0x40, 0xd0, 0x77, 0x8e, 0xfd, 0x30, - 0xe4, 0x36, 0xef, 0xf8, 0x51, 0x6e, 0x02, 0x55, 0x07, 0x23, 0xe8, 0xef, 0x71, 0x20, 0xf9, 0xff, - 0x00, 0xa3, 0x5c, 0x62, 0xf8, 0x57, 0x21, 0xcd, 0xf0, 0xdb, 0x82, 0x04, 0xa6, 0x03, 0x9c, 0x1d, - 0x7a, 0xb6, 0xff, 0x0d, 0xf9, 0x76, 0xf9, 0x6b, 0xb0, 0x2a, 0x24, 0xa3, 0x07, 0x7e, 0x74, 0x24, - 0x34, 0x2e, 0xcf, 0xa3, 0xae, 0x51, 0xd4, 0x25, 0x7f, 0x56, 0x02, 0x30, 0x1f, 0xd8, 0x32, 0xb2, - 0xfa, 0xab, 0x30, 0xd3, 0x66, 0x6c, 0x84, 0x3e, 0x1a, 0x05, 0x2e, 0xe4, 0xab, 0x5a, 0xf3, 0x10, - 0x83, 0xad, 0x46, 0x8a, 0xcf, 0x0c, 0xa5, 0x2e, 0x1a, 0x57, 0x23, 0x7f, 0x79, 0x98, 0xca, 0x6c, - 0x25, 0xb0, 0x48, 0x1d, 0x20, 0x89, 0x75, 0x2e, 0xb4, 0x1a, 0xab, 0x49, 0xd0, 0x60, 0x51, 0x20, - 0x32, 0x76, 0x26, 0x6f, 0xc9, 0xd5, 0xe9, 0x93, 0xa0, 0x91, 0x7b, 0x50, 0x6a, 0xbb, 0x71, 0x28, - 0xab, 0x09, 0x11, 0xe0, 0x31, 0x15, 0x7d, 0x2a, 0x0a, 0xfc, 0x72, 0xe4, 0x1e, 0xaa, 0xb5, 0x43, - 0x26, 0xc4, 0x82, 0xd9, 0x96, 0x3b, 0x74, 0x8f, 0xc3, 0x49, 0x99, 0x43, 0x78, 0xa9, 0xcc, 0x17, - 0x86, 0x40, 0x55, 0xa6, 0xe0, 0xc5, 0xe4, 0x36, 0x14, 0x6d, 0x7b, 0x4f, 0x3c, 0x8f, 0x58, 0x4a, - 0x6e, 0x13, 0xb6, 0xbd, 0xc7, 0x85, 0xde, 0x30, 0x3c, 0x56, 0xc8, 0x18, 0x32, 0xf9, 0x32, 0x2c, - 0x28, 0x97, 0x14, 0x11, 0x31, 0x18, 0xfb, 0x40, 0x79, 0xc8, 0xae, 0x6e, 0x1a, 0x0a, 0x36, 0xa9, - 0x83, 0x7e, 0x6f, 0xf4, 0xc8, 0x33, 0x07, 0x03, 0x8c, 0xa1, 0xf3, 0xb1, 0x37, 0xe4, 0x82, 0x5c, - 0x39, 0x49, 0xb5, 0x85, 0xaf, 0x46, 0xbb, 0xb2, 0x54, 0x55, 0x87, 0x64, 0x29, 0x49, 0x0b, 0x56, - 0x6d, 0x2f, 0x1a, 0x0d, 0xb8, 0x37, 0xe3, 0x36, 0xbf, 0x4e, 0xf3, 0xf8, 0xc2, 0x98, 0x95, 0x28, - 0x64, 0x85, 0xd2, 0x91, 0xf4, 0x60, 0xec, 0x4a, 0x3d, 0x4e, 0x6c, 0x78, 0xea, 0x90, 0xab, 0xf7, - 0x40, 0x6d, 0xda, 0x3d, 0xf0, 0x8d, 0x9c, 0x18, 0xf8, 0x78, 0x9b, 0x55, 0x62, 0xe0, 0xa7, 0x22, - 0xdf, 0x7f, 0xb7, 0xa4, 0xa4, 0x61, 0x11, 0x63, 0xf1, 0x2e, 0xc0, 0xdd, 0xc0, 0xef, 0xef, 0x79, - 0xd1, 0x51, 0xd0, 0x55, 0xc2, 0x14, 0x2c, 0x60, 0xb2, 0xf8, 0x63, 0x04, 0xff, 0xf5, 0xa7, 0x57, - 0x15, 0x24, 0xaa, 0xfc, 0x4d, 0x3e, 0xaf, 0xa6, 0x9a, 0x2f, 0x24, 0x31, 0x96, 0x93, 0x54, 0xf3, - 0x4a, 0x82, 0x79, 0x72, 0x07, 0x53, 0xfe, 0xfa, 0x83, 0x48, 0x11, 0x5e, 0x65, 0x7e, 0x5f, 0x7f, - 0x10, 0x65, 0x63, 0x14, 0x28, 0xc8, 0x64, 0x37, 0xae, 0xba, 0xcc, 0xd2, 0x2d, 0x32, 0x0b, 0x8b, - 0x40, 0x07, 0x58, 0xe4, 0xc8, 0x94, 0x3e, 0x6a, 0xa0, 0x83, 0x0c, 0x19, 0x56, 0xc2, 0xde, 0xad, - 0x0a, 0xdd, 0xc5, 0x8c, 0x52, 0x89, 0xf0, 0xa8, 0x2b, 0x34, 0x11, 0xa9, 0x4a, 0xc4, 0xc8, 0x64, - 0x0b, 0x56, 0xb8, 0xd4, 0x8f, 0x39, 0xbc, 0x31, 0xbd, 0xec, 0x6c, 0xb2, 0xb7, 0xf1, 0x6c, 0xdf, - 0xec, 0xde, 0xa1, 0x7e, 0x3e, 0x43, 0x40, 0xb6, 0x61, 0x06, 0xf5, 0x50, 0xe2, 0xfd, 0xe1, 0x25, - 0x55, 0x13, 0x9a, 0x5d, 0x47, 0xb8, 0xaf, 0xa0, 0x0e, 0x54, 0xdd, 0x57, 0x10, 0x95, 0xfc, 0x22, - 0x80, 0xd5, 0x1f, 0x06, 0xbd, 0x1e, 0x26, 0x9d, 0x2a, 0xa7, 0xe2, 0xa1, 0x08, 0x3e, 0xc8, 0x25, - 0x41, 0x12, 0x09, 0x12, 0xf0, 0xb7, 0x93, 0x49, 0x4d, 0xa5, 0xf0, 0x32, 0x6a, 0x30, 0xcb, 0x17, - 0x23, 0x26, 0x70, 0x13, 0x69, 0x6e, 0x95, 0xf4, 0x5f, 0x3c, 0x81, 0x9b, 0x80, 0x8f, 0x27, 0x70, - 0x53, 0x08, 0x8c, 0x7b, 0xb0, 0x96, 0xd7, 0xb0, 0x94, 0xe6, 0x4c, 0x3b, 0xad, 0xe6, 0xec, 0x0f, - 0x8a, 0xb0, 0x88, 0xdc, 0xe4, 0x2e, 0x6c, 0xc2, 0x92, 0x3d, 0x7a, 0x14, 0x47, 0x37, 0x97, 0xbb, - 0x31, 0xd6, 0x2f, 0x54, 0x0b, 0x54, 0x57, 0x87, 0x14, 0x05, 0xb1, 0x60, 0x59, 0x9e, 0x04, 0x3b, - 0xf2, 0xad, 0x5e, 0x9c, 0x3b, 0x4d, 0x3e, 0x61, 0x14, 0x1e, 0xfc, 0xaa, 0x5a, 0x2c, 0x4d, 0x94, - 0x9c, 0x07, 0xc5, 0x67, 0x39, 0x0f, 0x4a, 0xa7, 0x3a, 0x0f, 0x3e, 0x80, 0x45, 0xf9, 0x35, 0xdc, - 0xc9, 0x67, 0x9e, 0x6f, 0x27, 0x4f, 0x31, 0x23, 0xf5, 0x78, 0x47, 0x9f, 0x9d, 0xba, 0xa3, 0xa3, - 0xff, 0x88, 0x5c, 0x65, 0x03, 0x84, 0x8d, 0x6f, 0xec, 0xc6, 0x5f, 0x14, 0x01, 0x76, 0x2a, 0xad, - 0x9f, 0xe2, 0x94, 0x7c, 0x1b, 0xe6, 0xeb, 0x81, 0x74, 0x1d, 0x50, 0x6c, 0xb6, 0x3d, 0x09, 0x54, - 0xc5, 0x85, 0x18, 0x33, 0x3e, 0xdd, 0x8a, 0x9f, 0xc5, 0xe9, 0x76, 0x07, 0xb5, 0x83, 0x1f, 0x7a, - 0x9d, 0x28, 0x49, 0xe3, 0x8f, 0x4b, 0x46, 0x46, 0x19, 0x4d, 0x9b, 0x8e, 0x15, 0x64, 0xb6, 0x3b, - 0x09, 0xaf, 0x44, 0x19, 0xb5, 0x47, 0xe8, 0xe3, 0x70, 0x77, 0x92, 0xa1, 0x8f, 0x64, 0x20, 0x20, - 0x75, 0x7b, 0xc8, 0x90, 0x7d, 0xb6, 0x03, 0x42, 0xbe, 0x1a, 0xbb, 0x97, 0xcf, 0x4d, 0xeb, 0x21, - 0x63, 0xac, 0x87, 0x26, 0x3a, 0x95, 0x1b, 0xdf, 0xd7, 0xd4, 0xc4, 0x95, 0x3f, 0xc5, 0x50, 0x7f, - 0x11, 0x20, 0xf6, 0xdd, 0x92, 0x63, 0x1d, 0x07, 0x6c, 0xe1, 0x50, 0xb5, 0x97, 0x13, 0x5c, 0xa5, - 0x35, 0xc5, 0xcf, 0xaa, 0x35, 0x6d, 0x58, 0x68, 0x3e, 0x8e, 0xdc, 0xc4, 0xd9, 0x0f, 0xec, 0x58, - 0x92, 0xc5, 0x9d, 0xa9, 0x88, 0xca, 0xdd, 0x73, 0x8a, 0x1c, 0x3c, 0x41, 0x04, 0x56, 0x08, 0x8d, - 0xbf, 0xd1, 0x60, 0x45, 0x8d, 0xd9, 0x76, 0xd2, 0xef, 0x90, 0xf7, 0x78, 0x1e, 0x1d, 0x2d, 0x75, - 0x65, 0x51, 0x90, 0xd8, 0x96, 0x7b, 0xd2, 0xef, 0x70, 0x01, 0xc8, 0x7d, 0xa2, 0x56, 0x96, 0x11, - 0x92, 0x47, 0xb0, 0xd8, 0x0a, 0x7a, 0x3d, 0x26, 0xd6, 0x0c, 0x3f, 0x16, 0x17, 0x00, 0xc6, 0x28, - 0xab, 0x98, 0x94, 0x15, 0xda, 0x7a, 0x51, 0xdc, 0x73, 0x2f, 0x0c, 0xd8, 0x7e, 0xef, 0x0b, 0xba, - 0x84, 0xed, 0x77, 0xf0, 0x31, 0xbe, 0xca, 0x33, 0x39, 0x9b, 0xd2, 0x09, 0x18, 0xd5, 0x5a, 0xb2, - 0x62, 0xac, 0xe7, 0x94, 0xb3, 0xc9, 0xf8, 0x3b, 0x1a, 0x5c, 0x1b, 0x6f, 0x5a, 0xa5, 0x17, 0x8c, - 0xba, 0xed, 0xa1, 0xeb, 0xf7, 0xea, 0xc1, 0x61, 0xc8, 0xf3, 0x8f, 0x1c, 0x26, 0x76, 0x0e, 0x91, - 0x7f, 0xe4, 0xd0, 0xcf, 0xe6, 0x1f, 0xc1, 0x18, 0x1d, 0x6f, 0x41, 0xd9, 0xfe, 0xaa, 0xfd, 0xd5, - 0x91, 0x27, 0xef, 0xc2, 0x7c, 0x7f, 0x08, 0x3f, 0x0a, 0x9d, 0x8f, 0x18, 0x50, 0x3d, 0x31, 0x24, - 0xa2, 0xf1, 0xef, 0x0b, 0x40, 0xc6, 0xeb, 0xa1, 0x6e, 0xc1, 0xda, 0xff, 0x01, 0x91, 0x3c, 0x23, - 0xca, 0x96, 0x9e, 0x49, 0x94, 0xfd, 0x08, 0xf4, 0x0e, 0xeb, 0x47, 0x27, 0x62, 0x1d, 0xe9, 0xf4, - 0x82, 0xf8, 0x44, 0xf8, 0xdc, 0xc4, 0x39, 0x95, 0xee, 0x78, 0xbe, 0x27, 0x65, 0x99, 0xa8, 0x87, - 0x5b, 0x27, 0x85, 0x6f, 0xfc, 0xbe, 0x06, 0x6b, 0x79, 0x53, 0x80, 0x1d, 0x9e, 0xea, 0x69, 0x1a, - 0x9f, 0xe5, 0x78, 0x78, 0xaa, 0x07, 0x70, 0xfa, 0x44, 0xcf, 0x10, 0x65, 0xfb, 0xa3, 0xf0, 0x2c, - 0xfd, 0x61, 0xfc, 0xb8, 0x08, 0x8b, 0xdc, 0xb0, 0xbf, 0xeb, 0xb9, 0xbd, 0xe8, 0x88, 0x0d, 0xae, - 0x4c, 0x28, 0xac, 0xb8, 0x7f, 0x4f, 0xc9, 0x24, 0x7c, 0x1b, 0xca, 0x2d, 0xb6, 0x78, 0x3a, 0x41, - 0x4f, 0x55, 0x0a, 0x0e, 0x04, 0x4c, 0x9d, 0x58, 0x12, 0x8f, 0xcd, 0xdd, 0x94, 0x52, 0x9f, 0xe7, - 0xb0, 0x44, 0x88, 0x3a, 0x77, 0x85, 0x7a, 0xff, 0x13, 0x38, 0x9b, 0xf8, 0x6a, 0xc4, 0x86, 0x83, - 0x53, 0xbc, 0x74, 0xdb, 0x14, 0x56, 0x93, 0x2b, 0x89, 0xfb, 0x07, 0x5a, 0x18, 0xb0, 0x34, 0x93, - 0x54, 0x27, 0xef, 0x13, 0xe4, 0x1e, 0xe8, 0x09, 0x58, 0x64, 0xfb, 0xe1, 0x12, 0x2f, 0x46, 0xb3, - 0x53, 0xd8, 0x8e, 0x25, 0xfe, 0x19, 0x23, 0x64, 0x87, 0x5c, 0x02, 0xb3, 0x92, 0x47, 0xad, 0xd2, - 0x88, 0x18, 0xf3, 0x42, 0x9b, 0x85, 0x7a, 0xc8, 0x65, 0xc8, 0xd8, 0x18, 0x49, 0x53, 0xc7, 0x5c, - 0x32, 0x46, 0xc2, 0xc8, 0xa1, 0x8e, 0x91, 0xc0, 0xda, 0xfc, 0x6d, 0x0d, 0x56, 0x6a, 0xe6, 0x9e, - 0x48, 0x48, 0xcb, 0x7b, 0xf5, 0x3a, 0xbc, 0x50, 0x33, 0xf7, 0x9c, 0x56, 0xb3, 0x5e, 0xab, 0x3c, - 0x74, 0x72, 0xf3, 0xcc, 0xbd, 0x00, 0x17, 0xc7, 0x51, 0x12, 0xb7, 0x96, 0xcb, 0xb0, 0x3e, 0x5e, - 0x2c, 0x73, 0xd1, 0xe5, 0x13, 0xcb, 0xb4, 0x75, 0xc5, 0xcd, 0xf7, 0x61, 0x45, 0xe6, 0x5d, 0x6b, - 0xd7, 0x6d, 0xcc, 0xec, 0xba, 0x02, 0x0b, 0xf7, 0x2d, 0x5a, 0xdb, 0x7e, 0xe8, 0x6c, 0xef, 0xd7, - 0xeb, 0xfa, 0x19, 0xb2, 0x04, 0xf3, 0x02, 0x50, 0x31, 0x75, 0x8d, 0x2c, 0x42, 0xb9, 0xd6, 0xb0, - 0xad, 0xca, 0x3e, 0xb5, 0xf4, 0xc2, 0xe6, 0x3f, 0xd1, 0x60, 0x69, 0x7f, 0xd0, 0x75, 0x23, 0x6f, - 0x28, 0x5a, 0x74, 0x05, 0x36, 0xf6, 0x5b, 0x55, 0xb3, 0x6d, 0xd1, 0xfc, 0xe6, 0x9c, 0x83, 0xd5, - 0x4c, 0x79, 0xf3, 0x9e, 0xae, 0x91, 0x4b, 0x70, 0x21, 0x03, 0xae, 0xd6, 0x6c, 0x73, 0x8b, 0xb7, - 0xe2, 0x22, 0x9c, 0xcb, 0x14, 0xb6, 0x6a, 0x8d, 0x86, 0x55, 0xd5, 0x8b, 0xac, 0x81, 0x63, 0x9f, - 0xa3, 0x96, 0x59, 0x65, 0xa4, 0x7a, 0x69, 0xf3, 0x7d, 0x58, 0x6e, 0xc5, 0x6f, 0x78, 0xd0, 0x6b, - 0x66, 0x0e, 0x8a, 0xd4, 0x7c, 0xa0, 0x9f, 0x21, 0x00, 0xb3, 0xad, 0x7b, 0x15, 0xfb, 0xd6, 0x2d, - 0x5d, 0x23, 0x0b, 0x30, 0xb7, 0x53, 0x69, 0x39, 0xf7, 0xf6, 0x6c, 0xbd, 0xc0, 0x7e, 0x98, 0x0f, - 0x6c, 0xfc, 0x51, 0xdc, 0x7c, 0x13, 0x6d, 0xc5, 0x9f, 0x9c, 0xd4, 0xfd, 0x30, 0xf2, 0xfa, 0xde, - 0x10, 0xfb, 0x68, 0x11, 0xca, 0xb6, 0xc7, 0xe4, 0x95, 0xc8, 0xe3, 0x1d, 0xb4, 0x37, 0xea, 0x45, - 0xfe, 0xa0, 0xe7, 0x7d, 0xa2, 0x6b, 0x9b, 0x77, 0x60, 0x85, 0x06, 0xa3, 0xc8, 0xef, 0x1f, 0xda, - 0x11, 0xc3, 0x38, 0x3c, 0xc1, 0x36, 0x37, 0xcc, 0xbd, 0xad, 0xda, 0xce, 0x7e, 0x73, 0xdf, 0x76, - 0xf6, 0xcc, 0x76, 0x65, 0x97, 0xfb, 0xec, 0xec, 0x35, 0xed, 0xb6, 0x43, 0xad, 0x8a, 0xd5, 0x68, - 0xeb, 0xda, 0xe6, 0x6f, 0xa1, 0x06, 0xb7, 0x13, 0xf4, 0xbb, 0xdb, 0x6e, 0x27, 0x0a, 0x86, 0x58, - 0x61, 0x03, 0xae, 0xd8, 0x56, 0xa5, 0xd9, 0xa8, 0x3a, 0xdb, 0x66, 0xa5, 0xdd, 0xa4, 0x79, 0x89, - 0x18, 0x37, 0xe0, 0x7c, 0x0e, 0x4e, 0xb3, 0xdd, 0xd2, 0x35, 0x72, 0x15, 0x2e, 0xe5, 0x94, 0x3d, - 0xb0, 0xb6, 0xcc, 0xfd, 0xf6, 0x6e, 0x43, 0x2f, 0x4c, 0x20, 0xb6, 0xed, 0xa6, 0x5e, 0xdc, 0xfc, - 0x7b, 0x1a, 0x2c, 0xef, 0x87, 0xe2, 0x01, 0xe1, 0x3e, 0x1a, 0xec, 0xae, 0xc1, 0xe5, 0x7d, 0xdb, - 0xa2, 0x4e, 0xbb, 0x79, 0xcf, 0x6a, 0x38, 0xfb, 0xb6, 0xb9, 0x93, 0xad, 0xcd, 0x55, 0xb8, 0xa4, - 0x60, 0x50, 0xab, 0xd2, 0xbc, 0x6f, 0x51, 0xa7, 0x65, 0xda, 0xf6, 0x83, 0x26, 0xad, 0xea, 0x1a, - 0xfb, 0x62, 0x0e, 0xc2, 0xde, 0xb6, 0xc9, 0x6b, 0x93, 0x2a, 0x6b, 0x58, 0x0f, 0xcc, 0xba, 0xb3, - 0xd5, 0x6c, 0xeb, 0xc5, 0xcd, 0x3d, 0x76, 0x8b, 0xc0, 0x74, 0x68, 0xfc, 0x99, 0x47, 0x19, 0x4a, - 0x8d, 0x66, 0xc3, 0xca, 0x7a, 0x7a, 0x2d, 0x42, 0xd9, 0x6c, 0xb5, 0x68, 0xf3, 0x3e, 0x4e, 0x1e, - 0x80, 0xd9, 0xaa, 0xd5, 0xa8, 0xe1, 0x6c, 0x59, 0x84, 0x72, 0x8b, 0x36, 0xf7, 0x9a, 0x6d, 0xab, - 0xaa, 0x97, 0x36, 0x4d, 0x58, 0xe5, 0x47, 0x82, 0x60, 0x8a, 0x6a, 0xfe, 0x25, 0x98, 0xdf, 0x6f, - 0x54, 0xad, 0xed, 0x5a, 0x03, 0xdb, 0xb2, 0x0c, 0x60, 0xef, 0x36, 0x69, 0xdb, 0x69, 0x5b, 0x74, - 0x8f, 0xe7, 0xb7, 0xac, 0x37, 0x1b, 0x3b, 0xfc, 0x67, 0x61, 0x93, 0xca, 0xb3, 0x59, 0xd6, 0xab, - 0x13, 0x70, 0xcf, 0xac, 0xaa, 0xb5, 0x6d, 0xee, 0xd7, 0xdb, 0x62, 0x94, 0x1f, 0x3a, 0xd4, 0xfa, - 0xea, 0xbe, 0x65, 0xb7, 0x6d, 0x5d, 0x23, 0x3a, 0x2c, 0x36, 0x2c, 0xab, 0x6a, 0x3b, 0xd4, 0xba, - 0x5f, 0xb3, 0x1e, 0xe8, 0x05, 0x56, 0x2d, 0xfe, 0x37, 0xab, 0xe4, 0xe6, 0x77, 0x35, 0x20, 0x3c, - 0x1b, 0x9d, 0x4c, 0x71, 0x8e, 0x93, 0xee, 0x0a, 0x6c, 0xec, 0xb2, 0xd9, 0x82, 0xbd, 0xb3, 0xd7, - 0xac, 0x66, 0x7b, 0xfd, 0x3c, 0x90, 0x4c, 0x79, 0x73, 0x7b, 0x1b, 0x57, 0xd6, 0xd9, 0x0c, 0xbc, - 0x4a, 0x9b, 0x2d, 0xbd, 0xb0, 0x51, 0x28, 0x6b, 0xe4, 0xc2, 0x58, 0xe1, 0x3d, 0xcb, 0x6a, 0xe9, - 0x45, 0x36, 0xca, 0x99, 0x02, 0xb9, 0xea, 0x39, 0x79, 0x69, 0xf3, 0xdb, 0x1a, 0x9c, 0xe7, 0xd5, - 0x94, 0x5b, 0x48, 0x5c, 0xd5, 0xcb, 0xb0, 0x2e, 0x72, 0x6c, 0xe6, 0x55, 0x74, 0x0d, 0xf4, 0x54, - 0x29, 0xaf, 0xe6, 0x39, 0x58, 0x4d, 0x41, 0xb1, 0x1e, 0x05, 0xb6, 0x41, 0xa6, 0xc0, 0x5b, 0x96, - 0xdd, 0x76, 0xac, 0xed, 0x6d, 0x36, 0x24, 0x58, 0x91, 0xe2, 0xa6, 0x01, 0xab, 0x15, 0x6f, 0x18, - 0x59, 0x9f, 0x44, 0x5e, 0x3f, 0xf4, 0x83, 0x3e, 0x56, 0x61, 0x09, 0xe6, 0xad, 0x5f, 0x6c, 0x5b, - 0x0d, 0xbb, 0xd6, 0x6c, 0xe8, 0x67, 0x36, 0x2f, 0x67, 0x70, 0xe4, 0x56, 0x60, 0xdb, 0xbb, 0xfa, - 0x99, 0x4d, 0x17, 0x96, 0xe4, 0xd3, 0x3a, 0x3e, 0xb1, 0xae, 0xc0, 0x86, 0x9c, 0xae, 0xb8, 0xad, - 0x64, 0x9b, 0xb0, 0x0e, 0x6b, 0xe3, 0xe5, 0x56, 0x5b, 0xd7, 0xd8, 0x28, 0x64, 0x4a, 0x18, 0xbc, - 0xb0, 0xf9, 0x2d, 0x0d, 0x96, 0x62, 0x7b, 0x2f, 0x4e, 0xb4, 0xab, 0x70, 0x69, 0x6f, 0xdb, 0x74, - 0xaa, 0xd6, 0xfd, 0x5a, 0xc5, 0x72, 0xee, 0xd5, 0x1a, 0xd5, 0xcc, 0x47, 0x2e, 0xc2, 0xb9, 0x1c, - 0x04, 0xfc, 0xca, 0x3a, 0xac, 0x65, 0x8b, 0xda, 0x6c, 0xb5, 0x17, 0x58, 0xd7, 0x67, 0x4b, 0xe2, - 0xa5, 0x5e, 0xdc, 0xbc, 0x0f, 0xcb, 0xb6, 0xb9, 0x57, 0xdf, 0x0e, 0x86, 0x1d, 0xcf, 0x1c, 0x45, - 0x47, 0x7d, 0xb6, 0xef, 0x6e, 0x37, 0x69, 0xc5, 0x72, 0x10, 0x25, 0x53, 0x83, 0xb3, 0xb0, 0xa2, - 0x16, 0x3e, 0xb4, 0xd8, 0xf4, 0x25, 0xb0, 0xac, 0x02, 0x1b, 0x4d, 0xbd, 0xb0, 0xf9, 0x4b, 0xb0, - 0x28, 0x9c, 0x40, 0x78, 0xff, 0x5d, 0x80, 0xb3, 0xea, 0xef, 0x96, 0xd7, 0xef, 0xfa, 0xfd, 0x43, - 0xfd, 0x4c, 0xb6, 0x80, 0x8e, 0xfa, 0x7d, 0x56, 0x80, 0x5b, 0x82, 0x5a, 0xd0, 0xf6, 0x86, 0xc7, - 0x7e, 0xdf, 0x8d, 0xbc, 0xae, 0x5e, 0xd8, 0xbc, 0x09, 0x4b, 0xa9, 0xfc, 0x8a, 0x6c, 0xe0, 0xea, - 0x4d, 0xb1, 0x87, 0xef, 0x59, 0xd5, 0xda, 0xfe, 0x9e, 0x3e, 0xc3, 0x36, 0x83, 0xdd, 0xda, 0xce, - 0xae, 0x0e, 0x9b, 0xbf, 0xa3, 0xc1, 0xb2, 0xc8, 0x9a, 0xbe, 0xb7, 0x6d, 0xca, 0xa1, 0x66, 0xd3, - 0x8c, 0x67, 0x6d, 0xb5, 0x6c, 0x9b, 0xfb, 0x48, 0x5e, 0x86, 0x75, 0xf1, 0xc3, 0x31, 0x1b, 0x55, - 0x67, 0xd7, 0xa4, 0xd5, 0x07, 0x26, 0x65, 0x73, 0xef, 0xa1, 0x5e, 0xc0, 0x05, 0xa5, 0x40, 0x9c, - 0x76, 0x73, 0xbf, 0xb2, 0xab, 0x17, 0xd9, 0xfc, 0x4d, 0xc1, 0x5b, 0xb5, 0x86, 0x5e, 0xc2, 0xe5, - 0x39, 0x86, 0x8d, 0x6c, 0x59, 0xf9, 0xcc, 0xe6, 0x8f, 0x34, 0xb8, 0x60, 0xfb, 0x87, 0x7d, 0x37, - 0x1a, 0x0d, 0x3d, 0xb3, 0x77, 0x18, 0x0c, 0xfd, 0xe8, 0xe8, 0xd8, 0x1e, 0xf9, 0x91, 0x47, 0x5e, - 0x85, 0x97, 0xed, 0xda, 0x4e, 0xc3, 0x6c, 0xb3, 0xe5, 0x65, 0xd6, 0x77, 0x9a, 0xb4, 0xd6, 0xde, - 0xdd, 0x73, 0xec, 0xfd, 0xda, 0xd8, 0xcc, 0x7b, 0x09, 0xae, 0x4d, 0x46, 0xad, 0x5b, 0x3b, 0x66, - 0xe5, 0xa1, 0xae, 0x4d, 0x67, 0xb8, 0x65, 0xd6, 0xcd, 0x46, 0xc5, 0xaa, 0x3a, 0xf7, 0x6f, 0xe9, - 0x05, 0xf2, 0x32, 0x5c, 0x9f, 0x8c, 0xba, 0x5d, 0x6b, 0xd9, 0x0c, 0xad, 0x38, 0xfd, 0xbb, 0xbb, - 0xf6, 0x1e, 0xc3, 0x2a, 0x6d, 0xfe, 0xbe, 0x06, 0xeb, 0x93, 0x22, 0x8d, 0x93, 0x1b, 0x60, 0x58, - 0x8d, 0x36, 0x35, 0x6b, 0x55, 0xa7, 0x42, 0xad, 0xaa, 0xd5, 0x68, 0xd7, 0xcc, 0xba, 0xed, 0xd8, - 0xcd, 0x7d, 0x36, 0x9b, 0x12, 0x57, 0xd6, 0x17, 0xe1, 0xea, 0x14, 0xbc, 0x66, 0xad, 0x5a, 0xd1, - 0x35, 0x72, 0x0b, 0x5e, 0x9f, 0x82, 0x64, 0x3f, 0xb4, 0xdb, 0xd6, 0x9e, 0x5a, 0xa2, 0x17, 0x70, - 0xc3, 0xca, 0x0f, 0xb2, 0xcc, 0x5a, 0x87, 0x25, 0xd3, 0x2b, 0x76, 0x1d, 0x5e, 0x98, 0x88, 0x25, - 0xaa, 0xf5, 0x22, 0x5c, 0x9d, 0x88, 0xc2, 0x2b, 0xa5, 0x17, 0x36, 0x3f, 0x80, 0x8d, 0xc9, 0x81, - 0x3e, 0xd9, 0x79, 0x91, 0x1e, 0xf2, 0x32, 0x94, 0xaa, 0xec, 0x94, 0x4b, 0x65, 0x19, 0x66, 0xb3, - 0x93, 0x5a, 0xb5, 0xbd, 0x16, 0xdb, 0x08, 0xc5, 0xe1, 0x82, 0xa7, 0xc7, 0x37, 0x35, 0xd0, 0xb3, - 0x71, 0xf1, 0xc6, 0xbc, 0xa2, 0xe9, 0x7e, 0xa3, 0xc1, 0xcf, 0xca, 0x15, 0x58, 0x68, 0xb6, 0x77, - 0x2d, 0x2a, 0x12, 0x38, 0x63, 0xc6, 0xe6, 0xfd, 0x06, 0x5b, 0xda, 0x4d, 0x5a, 0xfb, 0x1a, 0x1e, - 0x9a, 0xeb, 0xb0, 0x66, 0xd7, 0xcd, 0xca, 0x3d, 0xa7, 0xd1, 0x6c, 0x3b, 0xb5, 0x86, 0x53, 0xd9, - 0x35, 0x1b, 0x0d, 0xab, 0xae, 0x03, 0xdb, 0xb3, 0x9b, 0xf7, 0xda, 0xa6, 0x53, 0x69, 0x36, 0xb6, - 0x6b, 0x3b, 0x82, 0xc5, 0x1a, 0xce, 0x82, 0x49, 0x71, 0x39, 0xc8, 0xe7, 0xe1, 0x15, 0xa4, 0x69, - 0xd5, 0xf7, 0x77, 0x6a, 0x0d, 0xc7, 0x7e, 0xd8, 0xa8, 0x48, 0xc9, 0xad, 0x32, 0x7e, 0x56, 0xbc, - 0x02, 0x2f, 0x4d, 0xc5, 0x4e, 0x32, 0x30, 0xdf, 0x00, 0x63, 0x2a, 0xa6, 0x68, 0xdf, 0xe6, 0x0f, - 0x34, 0xb8, 0x34, 0xc5, 0x6f, 0x87, 0xbc, 0x0e, 0xaf, 0xee, 0x5a, 0x66, 0xb5, 0x6e, 0xd9, 0x36, - 0xee, 0x70, 0x6c, 0x10, 0xb9, 0x53, 0x75, 0xee, 0x49, 0xf0, 0x2a, 0xbc, 0x3c, 0x1d, 0x3d, 0x11, - 0x4b, 0x5e, 0x81, 0x97, 0xa6, 0xa3, 0x0a, 0x31, 0xa5, 0x40, 0x36, 0xe1, 0xc6, 0x74, 0xcc, 0x58, - 0xbc, 0x29, 0x6e, 0xfe, 0xa6, 0x06, 0xe7, 0xf3, 0x55, 0xe5, 0xac, 0x6e, 0xb5, 0x86, 0xdd, 0x36, - 0xeb, 0x75, 0xa7, 0x65, 0x52, 0x73, 0xcf, 0xb1, 0x1a, 0xb4, 0x59, 0xaf, 0xe7, 0x9d, 0xc9, 0x2f, - 0xc1, 0xb5, 0xc9, 0xa8, 0x76, 0x85, 0xd6, 0x5a, 0xec, 0xd8, 0x31, 0xe0, 0xca, 0x64, 0x2c, 0xab, - 0x56, 0xb1, 0xf4, 0xc2, 0xd6, 0xbb, 0x7f, 0xf2, 0x17, 0x57, 0xce, 0xfc, 0xc9, 0x8f, 0xae, 0x68, - 0xff, 0xf1, 0x47, 0x57, 0xb4, 0x3f, 0xff, 0xd1, 0x15, 0xed, 0x6b, 0xaf, 0x71, 0x4f, 0xe5, 0x9b, - 0x9d, 0xe0, 0xf8, 0x8d, 0xc3, 0xa1, 0xfb, 0xb1, 0x1f, 0xb9, 0x3c, 0x65, 0xc7, 0x1b, 0xd2, 0xd2, - 0xf1, 0x86, 0x3b, 0xf0, 0xdf, 0xc0, 0x8b, 0xff, 0xa3, 0x59, 0xbc, 0x41, 0xbe, 0xf5, 0xbf, 0x02, - 0x00, 0x00, 0xff, 0xff, 0x7e, 0x6a, 0xc1, 0x5d, 0x37, 0xf0, 0x01, 0x00, + 0x1f, 0x84, 0x0b, 0x32, 0x18, 0xa7, 0xae, 0x0d, 0xca, 0xd0, 0x01, 0x19, 0xbf, 0x52, 0x80, 0x19, + 0x25, 0xe8, 0x18, 0xff, 0xd6, 0x63, 0xdc, 0x15, 0xf6, 0x61, 0x82, 0xb5, 0xc6, 0x69, 0x08, 0x77, + 0x34, 0x6e, 0xf8, 0xf2, 0x6a, 0xca, 0x1f, 0x5b, 0x70, 0xbb, 0xaa, 0x22, 0x73, 0xa3, 0x52, 0xdc, + 0x3a, 0xf1, 0x41, 0xa2, 0x91, 0x76, 0x45, 0xd3, 0x98, 0x93, 0x00, 0x26, 0x57, 0x0e, 0x5c, 0xbb, + 0x1d, 0xd5, 0xc6, 0x0d, 0x60, 0x3e, 0xdd, 0xb3, 0x36, 0x0d, 0x9b, 0x57, 0x17, 0x7b, 0x2e, 0xf2, + 0xb2, 0x8c, 0xa0, 0x19, 0x1a, 0xd5, 0xc2, 0x7b, 0x30, 0x93, 0xfa, 0xe8, 0x13, 0x45, 0xeb, 0x7d, + 0x08, 0x24, 0xfd, 0x1d, 0x83, 0x9b, 0x88, 0xb2, 0x33, 0xcf, 0x76, 0x9b, 0xdc, 0x9c, 0x66, 0x51, + 0x35, 0x11, 0xfd, 0xb9, 0xbc, 0xea, 0x13, 0xff, 0xac, 0xaf, 0xba, 0x2f, 0x68, 0xb7, 0xe1, 0xe7, + 0x7b, 0x8d, 0xe9, 0x40, 0x5a, 0x87, 0xef, 0x16, 0xe0, 0x4c, 0x0f, 0x4a, 0x72, 0x90, 0x9c, 0x44, + 0x5c, 0x0b, 0x71, 0xbd, 0x7f, 0x85, 0x4f, 0x63, 0x2a, 0x91, 0xcf, 0xf3, 0xa8, 0x38, 0x22, 0xe5, + 0x3c, 0xbf, 0x7f, 0xa3, 0x1a, 0x7f, 0x3f, 0x82, 0x26, 0xc3, 0xe1, 0x70, 0x28, 0x79, 0x0f, 0x86, + 0x31, 0x20, 0x42, 0x22, 0xec, 0x29, 0xc3, 0x40, 0xb8, 0x12, 0xb8, 0x97, 0xfd, 0xd4, 0x02, 0xf7, + 0x32, 0x00, 0xf9, 0x1c, 0x14, 0x2a, 0x0f, 0xeb, 0x62, 0x5c, 0xa6, 0x54, 0xf2, 0x87, 0xf5, 0x38, + 0x8d, 0x94, 0xad, 0xe5, 0x7b, 0x62, 0x14, 0x8c, 0xf0, 0xf6, 0x72, 0x4d, 0x8c, 0x8a, 0x4a, 0x78, + 0x7b, 0xb9, 0x16, 0x13, 0xee, 0xea, 0x2e, 0x97, 0xb7, 0x97, 0x6b, 0x9f, 0xdc, 0xb4, 0xff, 0x4f, + 0xf3, 0x3c, 0x94, 0x0f, 0x6f, 0xd8, 0x7b, 0x30, 0xa1, 0xc5, 0xea, 0xcf, 0xa9, 0x36, 0xe5, 0xc2, + 0xc0, 0x3e, 0x61, 0x31, 0xa4, 0x11, 0xc8, 0x84, 0x6c, 0x91, 0x0d, 0xbc, 0x6a, 0x6c, 0x13, 0x71, + 0x48, 0x7a, 0xb2, 0xe9, 0x24, 0xe4, 0x06, 0x14, 0x37, 0xa9, 0x6b, 0xbb, 0x61, 0xa4, 0x10, 0x45, + 0x43, 0xe5, 0x10, 0x61, 0xba, 0xd4, 0x10, 0x21, 0xa2, 0x4d, 0x6d, 0x77, 0x3b, 0x68, 0xf8, 0x0e, + 0x86, 0xfc, 0x8a, 0xce, 0x62, 0x6e, 0x53, 0xab, 0x94, 0xe8, 0x0c, 0x12, 0x44, 0xc6, 0xcf, 0xe5, + 0x60, 0x54, 0x0c, 0x24, 0x4f, 0xa4, 0xb9, 0x1b, 0x9f, 0x25, 0xc2, 0x77, 0x65, 0xd7, 0x49, 0xfa, + 0xae, 0xec, 0xf2, 0xb8, 0x5a, 0x63, 0xc2, 0x69, 0x34, 0x7a, 0x1a, 0xc4, 0xd9, 0x28, 0xdd, 0xa1, + 0xf5, 0x3c, 0x89, 0x11, 0xea, 0xa0, 0x4e, 0x84, 0xc6, 0xdf, 0x10, 0x5f, 0x76, 0x7b, 0xb9, 0x46, + 0x16, 0xa1, 0xb8, 0xee, 0xf1, 0x10, 0x71, 0x6a, 0x56, 0xf8, 0x96, 0x80, 0xa9, 0x1d, 0x24, 0xf1, + 0xd8, 0xf7, 0xd5, 0x7c, 0x4f, 0xdc, 0x65, 0x94, 0xef, 0xeb, 0x70, 0x60, 0xe2, 0xfb, 0x22, 0xd4, + 0x81, 0xbf, 0x8f, 0x66, 0x6c, 0x12, 0x0f, 0x6e, 0xa0, 0x7f, 0xc1, 0x1d, 0xd5, 0x39, 0x53, 0x14, + 0xc9, 0x9d, 0x62, 0xa1, 0xd7, 0x4e, 0xf1, 0xe0, 0x86, 0x99, 0x41, 0x85, 0xef, 0x6a, 0x31, 0xb8, + 0x4e, 0xfd, 0x47, 0xcf, 0xf0, 0x2e, 0x9d, 0xfd, 0xae, 0x96, 0x6c, 0xde, 0x40, 0x9b, 0xf4, 0xef, + 0xe6, 0xe1, 0x74, 0x36, 0xa1, 0xda, 0x96, 0x5c, 0x9f, 0xb6, 0x5c, 0x82, 0xe2, 0x9a, 0x17, 0x84, + 0x8a, 0x91, 0x20, 0xaa, 0xff, 0xf7, 0x04, 0xcc, 0x8c, 0x4a, 0xd9, 0x9d, 0x9b, 0xfd, 0x1d, 0x2d, + 0x4f, 0xe4, 0x87, 0x01, 0x6c, 0xd8, 0x9d, 0x9b, 0x17, 0x91, 0xdb, 0x50, 0x34, 0x85, 0x9f, 0x5f, + 0xa2, 0x6b, 0x24, 0x38, 0x92, 0xa6, 0x88, 0x2f, 0x20, 0x5a, 0xca, 0x04, 0x01, 0x23, 0x15, 0x18, + 0x15, 0xa3, 0x9f, 0x78, 0x3a, 0xce, 0x98, 0x32, 0x7a, 0x16, 0x13, 0x49, 0xc7, 0x76, 0x14, 0x7c, + 0x04, 0xac, 0xae, 0x48, 0x97, 0x3d, 0xdc, 0x51, 0xf8, 0x23, 0xa1, 0x6e, 0x8f, 0x19, 0x21, 0x1a, + 0xdf, 0xcc, 0x03, 0x48, 0xad, 0xcd, 0x33, 0x3b, 0xc3, 0x3e, 0xa7, 0xcd, 0x30, 0xc5, 0xde, 0x68, + 0xf0, 0x6c, 0xf5, 0xf7, 0xd1, 0x9c, 0x67, 0xf0, 0x5c, 0xf5, 0x65, 0x18, 0xde, 0x8c, 0x15, 0x5a, + 0xc2, 0xbd, 0x05, 0xd5, 0xd1, 0x1c, 0x6e, 0x6c, 0xc3, 0xdc, 0x6d, 0x1a, 0xc6, 0xea, 0x2d, 0xf9, + 0xf4, 0xd8, 0x9f, 0xed, 0x6b, 0x30, 0x26, 0xf0, 0xa3, 0xfd, 0x8b, 0xeb, 0x62, 0x44, 0x4c, 0x28, + 0xd4, 0xc5, 0x48, 0x04, 0xb6, 0x1b, 0xad, 0xd0, 0x16, 0x0d, 0xe9, 0x27, 0x5b, 0x4d, 0x1d, 0x08, + 0x6f, 0x0a, 0xb6, 0x6c, 0xb0, 0x1a, 0x8e, 0xed, 0x9f, 0x07, 0x70, 0x2a, 0xfa, 0xf6, 0xa7, 0xc9, + 0xf7, 0x1a, 0xbb, 0x52, 0x8a, 0x04, 0x20, 0x31, 0xc7, 0x3e, 0xb6, 0x27, 0xbf, 0x9f, 0x83, 0x05, + 0x49, 0xf1, 0xd0, 0x89, 0x2c, 0x27, 0x07, 0x22, 0x26, 0x6f, 0xc3, 0xb8, 0x42, 0x23, 0x3c, 0x53, + 0x50, 0x4f, 0xfd, 0xd8, 0x09, 0xf7, 0xac, 0x80, 0xc3, 0x55, 0x3d, 0xb5, 0x82, 0x4e, 0xb6, 0x61, + 0xa1, 0x5e, 0xd9, 0x58, 0x8f, 0x7d, 0xcb, 0xee, 0x79, 0xb7, 0xbc, 0x56, 0xcb, 0x7b, 0xbc, 0x65, + 0xae, 0xcb, 0x34, 0x54, 0x18, 0xf8, 0x06, 0x95, 0xde, 0x8a, 0x83, 0x9a, 0xeb, 0x59, 0x3b, 0x88, + 0x68, 0x75, 0xfd, 0x56, 0x60, 0xf6, 0xe1, 0x62, 0xfc, 0xe3, 0x1c, 0x9c, 0x8b, 0x1c, 0x9d, 0x32, + 0xda, 0x97, 0x68, 0x41, 0xee, 0x69, 0xb6, 0x20, 0xff, 0x54, 0x5a, 0x70, 0x2f, 0x1e, 0x9f, 0xaa, + 0x1b, 0xc5, 0x25, 0x90, 0xdf, 0x4f, 0xd4, 0xf1, 0x11, 0xa3, 0xf2, 0x5c, 0x2a, 0xd2, 0x81, 0x12, + 0xd0, 0xc0, 0x78, 0x4b, 0xe9, 0x90, 0x0c, 0x86, 0x1a, 0x71, 0x2e, 0x49, 0xfc, 0xcd, 0x3c, 0x4c, + 0xdf, 0xaf, 0xae, 0x2c, 0x47, 0x76, 0x54, 0xcf, 0xec, 0xa6, 0x99, 0x6d, 0xa9, 0xa4, 0xb5, 0xad, + 0xf7, 0xce, 0x69, 0x6c, 0xc1, 0x6c, 0xa2, 0x1b, 0x50, 0x08, 0x7a, 0x97, 0xbb, 0xce, 0x44, 0x60, + 0x29, 0x00, 0x9d, 0xce, 0x62, 0xff, 0xe0, 0x86, 0x99, 0xc0, 0x36, 0xfe, 0xd5, 0x44, 0x82, 0xaf, + 0xd8, 0x8c, 0x5f, 0x83, 0xb1, 0x6a, 0x10, 0x74, 0xa9, 0xbf, 0x65, 0xae, 0xab, 0x4a, 0x0f, 0x07, + 0x81, 0x6c, 0x0e, 0x99, 0x31, 0x02, 0xb9, 0x0c, 0x45, 0x91, 0x06, 0x41, 0xee, 0x6e, 0xa8, 0x7f, + 0x8e, 0xb2, 0x28, 0x98, 0x51, 0x31, 0x79, 0x1d, 0x26, 0xf8, 0xdf, 0x7c, 0x46, 0x8b, 0x0e, 0x47, + 0x35, 0xa7, 0x40, 0xe7, 0x2b, 0xc0, 0xd4, 0xd0, 0xc8, 0xab, 0x50, 0xa8, 0x2c, 0x9b, 0x42, 0xb1, + 0x25, 0x24, 0x60, 0xdf, 0xe2, 0xda, 0x47, 0xed, 0x3a, 0xb4, 0x6c, 0x32, 0x39, 0x56, 0x86, 0x84, + 0x11, 0x3a, 0x79, 0x9c, 0x01, 0x52, 0x6f, 0x96, 0x38, 0x96, 0x11, 0x46, 0xae, 0xc1, 0xe8, 0x0a, + 0x37, 0xfe, 0x13, 0x1a, 0x79, 0x9e, 0x3d, 0x96, 0x83, 0xb4, 0xd0, 0x26, 0x1c, 0x44, 0x2e, 0xcb, + 0xc4, 0x8d, 0xc5, 0xd8, 0x03, 0xa7, 0x47, 0x76, 0xc6, 0xd7, 0x60, 0x44, 0x24, 0x0b, 0x18, 0x53, + 0xb2, 0x33, 0x25, 0x93, 0x04, 0x08, 0x9c, 0xb4, 0x27, 0x38, 0x3c, 0x4d, 0x4f, 0xf0, 0x6d, 0x38, + 0x73, 0x1b, 0xf5, 0x50, 0x7a, 0xc8, 0xbb, 0x2d, 0xb3, 0x2a, 0x34, 0xfb, 0xf8, 0xa0, 0xc5, 0x55, + 0x55, 0xc9, 0xa8, 0x79, 0x56, 0xd7, 0x57, 0x93, 0xa1, 0xf7, 0x62, 0x44, 0x3e, 0x80, 0xb9, 0xac, + 0x22, 0xa1, 0xff, 0xc7, 0xe0, 0x6e, 0xd9, 0x15, 0xa8, 0xc1, 0xdd, 0xb2, 0x38, 0x90, 0x75, 0x28, + 0x71, 0x78, 0xa5, 0xd9, 0x76, 0x5c, 0xfe, 0x86, 0x31, 0x19, 0x7b, 0x14, 0x0b, 0xae, 0x36, 0x2b, + 0xe4, 0x6f, 0x19, 0x9a, 0x13, 0x55, 0x82, 0x92, 0xfc, 0x64, 0x8e, 0xdd, 0x4b, 0x79, 0x68, 0x7d, + 0xdc, 0x3e, 0xa7, 0xc4, 0x6b, 0x68, 0xe4, 0xd5, 0x54, 0x0f, 0x7d, 0xc7, 0xdd, 0x15, 0x0e, 0x52, + 0x9b, 0xc2, 0x41, 0xea, 0xed, 0x8f, 0xe4, 0x20, 0xc5, 0x59, 0x05, 0x47, 0x87, 0xe5, 0x09, 0x5f, + 0xd4, 0x89, 0xab, 0x48, 0xfb, 0x02, 0xd6, 0x75, 0xe8, 0xa4, 0xbe, 0xe5, 0xf2, 0xc0, 0xde, 0xb4, + 0xc9, 0x1b, 0x39, 0x8d, 0x1b, 0x3b, 0x76, 0x9d, 0xcd, 0x37, 0xf1, 0x08, 0x21, 0xd5, 0xd0, 0x4c, + 0x0e, 0xec, 0x0a, 0x2d, 0x9d, 0x70, 0xb8, 0x8f, 0x72, 0x29, 0xbe, 0x42, 0x4b, 0x8f, 0x1d, 0x0b, + 0xa7, 0x91, 0x3a, 0x79, 0x34, 0x12, 0x72, 0x0d, 0x46, 0x36, 0xec, 0x27, 0x95, 0x5d, 0x2a, 0xb2, + 0x25, 0x4f, 0xca, 0xed, 0x0f, 0x81, 0x4b, 0xc5, 0xdf, 0xe3, 0x5e, 0x1b, 0x9f, 0x32, 0x05, 0x1a, + 0xf9, 0x0b, 0x39, 0x38, 0xcd, 0x97, 0xb1, 0x6c, 0x65, 0x9d, 0x86, 0x21, 0xeb, 0x07, 0x11, 0x21, + 0xf4, 0x42, 0x6c, 0x7a, 0x9e, 0x8d, 0x87, 0x21, 0x2c, 0x0c, 0xb1, 0x33, 0x44, 0x1d, 0x17, 0x88, + 0x52, 0x2d, 0xd4, 0x7a, 0x26, 0x3d, 0xd9, 0x84, 0xf1, 0x8d, 0x5b, 0x95, 0xa8, 0xda, 0x59, 0x2d, + 0x5b, 0xae, 0xb6, 0xf3, 0x29, 0x68, 0x59, 0x3e, 0x13, 0x2a, 0x1b, 0x14, 0xfd, 0xef, 0x2e, 0xaf, + 0x62, 0xd4, 0x88, 0xb9, 0x58, 0x99, 0xd0, 0xd9, 0x6f, 0xd0, 0x64, 0x0c, 0xf8, 0x08, 0x91, 0xbc, + 0xc7, 0xdd, 0x38, 0x31, 0xb6, 0x10, 0xbb, 0xaa, 0x9e, 0x8a, 0xc3, 0xb8, 0xf2, 0xe0, 0xf1, 0xa2, + 0x40, 0x55, 0x83, 0xa8, 0x04, 0xe4, 0x3e, 0xc8, 0x28, 0x14, 0xdc, 0x2a, 0x1c, 0xab, 0x3f, 0x1d, + 0xbb, 0x4e, 0x49, 0x53, 0x00, 0x6e, 0x4c, 0x9e, 0xfc, 0x90, 0x34, 0x2d, 0xd9, 0x82, 0x79, 0xea, + 0x86, 0xbe, 0x6d, 0x39, 0x4d, 0x11, 0xf0, 0x31, 0x7a, 0x5d, 0x10, 0x39, 0x92, 0xa5, 0x5e, 0x7d, + 0x95, 0xa1, 0x55, 0x57, 0xf8, 0x7b, 0xa3, 0xdc, 0x35, 0xcd, 0x53, 0x48, 0x5d, 0x6d, 0xea, 0x60, + 0xe1, 0x05, 0x72, 0x00, 0xa7, 0x32, 0xa9, 0xc8, 0x02, 0x14, 0x9b, 0x4e, 0x10, 0x27, 0x75, 0x2a, + 0x9a, 0xd1, 0x6f, 0x72, 0x1e, 0x80, 0x07, 0xca, 0x53, 0x6c, 0xb7, 0xc7, 0x10, 0x82, 0x4f, 0x45, + 0x2f, 0xc3, 0xd4, 0xae, 0x6f, 0x77, 0xf6, 0x2c, 0xea, 0x36, 0x3b, 0x9e, 0xe3, 0x8a, 0xf3, 0xc3, + 0x9c, 0x44, 0xe8, 0xaa, 0x00, 0x1a, 0x9f, 0x93, 0x13, 0x95, 0x5c, 0x51, 0x3d, 0xa7, 0x0b, 0x38, + 0x4a, 0xa3, 0x6d, 0xfb, 0x89, 0x65, 0xef, 0x52, 0xcd, 0x10, 0x43, 0x3c, 0x90, 0xfc, 0x4c, 0x0e, + 0xce, 0xf6, 0x9c, 0x8b, 0xe4, 0x26, 0x9c, 0xb1, 0x79, 0x08, 0x09, 0x6b, 0x2f, 0x0c, 0x3b, 0x81, + 0x25, 0x6f, 0xb1, 0x32, 0xd0, 0xd6, 0x29, 0x51, 0xbc, 0xc6, 0x4a, 0xe5, 0xc5, 0x36, 0x20, 0xef, + 0xc1, 0x73, 0x8e, 0x1b, 0xd0, 0x46, 0xd7, 0xa7, 0x96, 0x64, 0xd0, 0x70, 0x9a, 0xbe, 0xe5, 0xdb, + 0xee, 0xae, 0x74, 0x1c, 0x37, 0xcf, 0x4a, 0x1c, 0x11, 0xa6, 0x62, 0xd9, 0x69, 0xfa, 0x26, 0x22, + 0x18, 0xbf, 0x9c, 0x87, 0xf9, 0x5e, 0x73, 0x95, 0xcc, 0xc3, 0x28, 0x75, 0xd5, 0xde, 0x94, 0x3f, + 0xc9, 0x39, 0x88, 0x8f, 0x60, 0xd1, 0x97, 0xc5, 0x86, 0x48, 0x57, 0x84, 0xde, 0x13, 0xea, 0x81, + 0x2b, 0x7a, 0x72, 0xa2, 0xa1, 0x1e, 0xbb, 0xe7, 0x01, 0xe2, 0x73, 0x96, 0xeb, 0xbe, 0xcc, 0x31, + 0xbb, 0xe1, 0xf3, 0x2d, 0x91, 0x9c, 0x86, 0x11, 0x7e, 0x8e, 0x09, 0x17, 0x1b, 0xf1, 0x8b, 0x09, + 0x54, 0xa2, 0x93, 0xf1, 0x00, 0x2e, 0x2c, 0x4d, 0x68, 0x9d, 0x3d, 0xd2, 0xe6, 0x83, 0x93, 0x39, + 0x9f, 0x47, 0x3f, 0xfa, 0x7c, 0x36, 0x7e, 0x7d, 0x82, 0x0b, 0x8b, 0x95, 0x6e, 0xb8, 0x27, 0xc5, + 0xcb, 0xc5, 0x2c, 0x1f, 0x47, 0x6e, 0xff, 0xab, 0xf8, 0x12, 0xe8, 0x9e, 0x8d, 0xf2, 0xbd, 0x32, + 0x9f, 0xf9, 0x5e, 0xf9, 0x1a, 0x8c, 0x2d, 0xef, 0xd1, 0xc6, 0x7e, 0xe4, 0x38, 0x56, 0x14, 0x0f, + 0x42, 0x0c, 0xc8, 0xd3, 0x5b, 0xc4, 0x08, 0xe4, 0x1a, 0x00, 0xba, 0x56, 0xf3, 0x5b, 0x94, 0x92, + 0xa2, 0x0a, 0x3d, 0xb1, 0x85, 0x49, 0x95, 0x82, 0x82, 0xec, 0xeb, 0xe6, 0x2d, 0xd5, 0x06, 0x8b, + 0xb3, 0x0f, 0xfc, 0x1d, 0x81, 0x1e, 0x23, 0xb0, 0xe6, 0x29, 0x27, 0x88, 0x90, 0x77, 0x4a, 0xa9, + 0x63, 0x46, 0x45, 0x22, 0x9f, 0x83, 0xd1, 0x65, 0xea, 0x87, 0x9b, 0x9b, 0xeb, 0x68, 0xf8, 0xc4, + 0x33, 0x33, 0x15, 0x31, 0x8b, 0x4e, 0x18, 0xb6, 0xbe, 0x77, 0x58, 0x9e, 0x0c, 0x9d, 0x36, 0x8d, + 0x32, 0x4e, 0x98, 0x12, 0x9b, 0x2c, 0x41, 0x89, 0x9b, 0x66, 0xc4, 0xf7, 0x5f, 0x94, 0x69, 0x8a, + 0x5c, 0xc2, 0x12, 0x76, 0x1c, 0x8f, 0xe9, 0x76, 0x94, 0x43, 0x28, 0x85, 0x4f, 0x56, 0x65, 0xea, + 0x2d, 0xf5, 0xb3, 0x21, 0xde, 0x43, 0x93, 0x7b, 0x3d, 0xfb, 0xfa, 0x34, 0x05, 0xa9, 0xc0, 0xe4, + 0xb2, 0xd7, 0xee, 0xd8, 0xa1, 0x83, 0x89, 0x8d, 0x0f, 0x84, 0xf8, 0x82, 0xbb, 0x69, 0x43, 0x2d, + 0xd0, 0x64, 0x21, 0xb5, 0x80, 0xdc, 0x82, 0x29, 0xd3, 0xeb, 0xb2, 0x6e, 0x97, 0x9a, 0x20, 0x2e, + 0xa1, 0xa0, 0x79, 0x92, 0xcf, 0x4a, 0x98, 0x40, 0x25, 0xd4, 0x3e, 0x5a, 0x74, 0x6e, 0x8d, 0x8a, + 0xdc, 0xcb, 0x78, 0x92, 0x53, 0xc5, 0x12, 0x35, 0x93, 0x50, 0x8a, 0x59, 0xc6, 0x6b, 0xde, 0x0d, + 0x18, 0xaf, 0xd7, 0xef, 0x6f, 0xd2, 0x20, 0xbc, 0xd5, 0xf2, 0x1e, 0xa3, 0x54, 0x52, 0x14, 0x89, + 0x2f, 0x03, 0xcf, 0x0a, 0xd9, 0x8a, 0xd8, 0x69, 0x79, 0x8f, 0x4d, 0x15, 0x8b, 0x7c, 0x95, 0xf5, + 0x87, 0x22, 0xc3, 0x8b, 0x38, 0xe4, 0xfd, 0xae, 0x19, 0x78, 0xf6, 0xc7, 0x8b, 0x80, 0x5d, 0x36, + 0xf4, 0xce, 0x52, 0xd0, 0xd1, 0xaf, 0xd1, 0xf7, 0x9e, 0x1c, 0x54, 0x9a, 0x4d, 0x9f, 0x06, 0x81, + 0x10, 0x1f, 0xb8, 0x5f, 0x23, 0x2a, 0xbc, 0x6c, 0x5e, 0xa0, 0xf9, 0x35, 0x2a, 0x04, 0x64, 0x99, + 0xc9, 0xb5, 0x6c, 0x14, 0xd1, 0x60, 0xae, 0x5a, 0x43, 0x09, 0x40, 0x68, 0xd2, 0xc5, 0x98, 0x73, + 0xd3, 0x3a, 0xa7, 0xa3, 0x8b, 0xaf, 0x0a, 0x0d, 0xa9, 0xc2, 0x34, 0x07, 0xb0, 0xa5, 0xc5, 0xd3, + 0xde, 0xcd, 0xc6, 0x89, 0x77, 0x04, 0x1b, 0x3c, 0x4c, 0x31, 0xf5, 0x9d, 0x1a, 0x9c, 0x22, 0x41, + 0x47, 0xde, 0x83, 0x29, 0xcc, 0x29, 0x12, 0x39, 0x87, 0xe1, 0x41, 0x3e, 0xc1, 0x63, 0x6e, 0x8b, + 0x92, 0x84, 0xc7, 0xe5, 0x44, 0x10, 0xec, 0xd5, 0xa4, 0xd7, 0x18, 0x63, 0x80, 0x36, 0x5a, 0x31, + 0x83, 0x53, 0x31, 0x03, 0x51, 0x92, 0x64, 0x10, 0xb6, 0x82, 0x98, 0xc1, 0x4f, 0xe7, 0xe0, 0x2c, + 0xab, 0x48, 0xf5, 0x03, 0xc3, 0x4d, 0x01, 0x0d, 0xd0, 0x78, 0x3e, 0xa4, 0x2b, 0x57, 0xa5, 0x50, + 0x79, 0x55, 0x41, 0xbb, 0xfa, 0xe8, 0xfa, 0xd5, 0x4a, 0xfc, 0xb3, 0x2e, 0x89, 0x78, 0x14, 0xe2, + 0x9e, 0x3c, 0x55, 0xe1, 0x3d, 0x08, 0xf6, 0xb2, 0x38, 0xe0, 0x47, 0xb1, 0x8f, 0xcf, 0xfe, 0xa8, + 0x33, 0x1f, 0xf9, 0xa3, 0x7a, 0xf2, 0x54, 0x3f, 0x2a, 0x6c, 0x05, 0x99, 0x1f, 0x75, 0x13, 0x26, + 0x51, 0xb4, 0x12, 0x22, 0xad, 0x2f, 0xb2, 0x2d, 0xe1, 0x9a, 0xd0, 0x0a, 0xcc, 0x09, 0xf6, 0xf3, + 0x81, 0xf8, 0x75, 0x67, 0xa8, 0x38, 0x5a, 0x2a, 0xde, 0x19, 0x2a, 0xce, 0x94, 0x88, 0x39, 0x16, + 0x75, 0xbc, 0x79, 0x2a, 0xf3, 0x43, 0x50, 0xd5, 0x50, 0xaf, 0x6c, 0xac, 0xc7, 0xf7, 0xe5, 0xef, + 0x2f, 0xa7, 0x28, 0xad, 0x6d, 0x7d, 0x9c, 0xa2, 0xb6, 0xb8, 0x8f, 0xbe, 0xd2, 0x0d, 0x52, 0xd5, + 0xa0, 0x81, 0x93, 0xaa, 0x86, 0x04, 0x8d, 0x99, 0xc0, 0x36, 0x7e, 0x7b, 0x3c, 0xc1, 0x57, 0x18, + 0x42, 0x1b, 0x30, 0xc2, 0x35, 0x09, 0xa2, 0x93, 0xd1, 0x22, 0x86, 0xeb, 0x19, 0x4c, 0x51, 0x42, + 0xce, 0x42, 0xa1, 0x5e, 0xbf, 0x2f, 0x3a, 0x19, 0xcd, 0xa1, 0x83, 0xc0, 0x33, 0x19, 0x8c, 0x8d, + 0x10, 0xda, 0x38, 0x2b, 0x99, 0x60, 0xd8, 0x49, 0x66, 0x22, 0x94, 0xf5, 0xb7, 0xbc, 0xd7, 0x0f, + 0xc5, 0xfd, 0x2d, 0xee, 0xf5, 0xf1, 0x6d, 0x7e, 0x19, 0xe6, 0x2b, 0x41, 0x40, 0x7d, 0x36, 0x23, + 0x84, 0xe9, 0xac, 0x2f, 0xee, 0x9e, 0xe2, 0x08, 0xc6, 0x4a, 0xed, 0x46, 0x60, 0xf6, 0x44, 0x24, + 0x97, 0xa0, 0x58, 0xe9, 0x36, 0x1d, 0xea, 0x36, 0xb4, 0x98, 0x93, 0xb6, 0x80, 0x99, 0x51, 0x29, + 0x79, 0x1f, 0x4e, 0x25, 0x62, 0xd7, 0x8a, 0x1e, 0x18, 0x8d, 0x77, 0x55, 0x79, 0x37, 0x8e, 0xcd, + 0x7d, 0x78, 0x97, 0x64, 0x53, 0x92, 0x0a, 0x94, 0x56, 0xd1, 0x09, 0x70, 0x85, 0xf2, 0x97, 0x47, + 0xcf, 0xe7, 0xde, 0x9f, 0x5c, 0x93, 0x21, 0xa2, 0xfb, 0x36, 0xa3, 0x42, 0x33, 0x85, 0x4e, 0xee, + 0xc2, 0x6c, 0x12, 0xc6, 0xce, 0x66, 0xae, 0xb4, 0xc0, 0x5d, 0x2d, 0xc5, 0x05, 0x4f, 0xe7, 0x2c, + 0x2a, 0xb2, 0x0d, 0x33, 0xb1, 0xb9, 0x9b, 0xae, 0xca, 0x90, 0x56, 0xf4, 0x51, 0xb9, 0x54, 0x67, + 0x9c, 0x13, 0x93, 0x71, 0x36, 0x36, 0x9d, 0x8b, 0x54, 0x1a, 0x66, 0x9a, 0x1d, 0x69, 0xc2, 0x54, + 0xdd, 0xd9, 0x75, 0x1d, 0x77, 0xf7, 0x2e, 0x3d, 0xa8, 0xd9, 0x8e, 0x2f, 0xec, 0x99, 0xa5, 0xb7, + 0x42, 0x25, 0x38, 0x68, 0xb7, 0x69, 0xe8, 0xe3, 0xaa, 0x67, 0xe5, 0x18, 0xe1, 0x80, 0x5d, 0x51, + 0x17, 0x02, 0x4e, 0x87, 0x4e, 0xc1, 0x1d, 0xdb, 0xd1, 0x8e, 0x77, 0x9d, 0xa7, 0xa6, 0x4e, 0x9a, + 0x18, 0x50, 0x9d, 0xd4, 0x82, 0x99, 0x55, 0xb7, 0xe1, 0x1f, 0xe0, 0x03, 0xb0, 0xfc, 0xb8, 0xc9, + 0x63, 0x3e, 0xee, 0x25, 0xf1, 0x71, 0xcf, 0xd9, 0x72, 0x86, 0x65, 0x7d, 0x5e, 0x9a, 0x31, 0xa9, + 0xc3, 0x0c, 0xde, 0x19, 0xaa, 0x2b, 0xb5, 0xaa, 0xeb, 0x84, 0x8e, 0x1d, 0xd2, 0xa6, 0x10, 0x1b, + 0xa2, 0xfc, 0x59, 0x5c, 0x6d, 0xe0, 0x34, 0x3b, 0x96, 0x23, 0x51, 0x54, 0xa6, 0x29, 0xfa, 0x7e, + 0x77, 0xf7, 0xe9, 0x3f, 0xa1, 0xbb, 0x7b, 0x15, 0xa6, 0x93, 0x81, 0x42, 0x4a, 0xf1, 0x69, 0x1f, + 0x60, 0x11, 0x13, 0x1a, 0xbc, 0x2e, 0x8a, 0x89, 0x5a, 0x28, 0xaa, 0x44, 0x88, 0x90, 0x84, 0x1a, + 0x60, 0x46, 0x53, 0x03, 0x68, 0xbb, 0xd2, 0x49, 0xd4, 0x00, 0x35, 0x80, 0x5b, 0x9e, 0xdf, 0xa0, + 0x15, 0xf4, 0xbe, 0x27, 0x5a, 0x96, 0x41, 0xc6, 0x34, 0x2e, 0xe4, 0xeb, 0x67, 0x87, 0xfd, 0xb6, + 0x92, 0x41, 0x14, 0x14, 0x1e, 0xc4, 0x86, 0x33, 0x35, 0x9f, 0xee, 0x50, 0xdf, 0xa7, 0x4d, 0x71, + 0x83, 0x59, 0x72, 0xdc, 0xa6, 0x4c, 0x1d, 0x29, 0xf2, 0x0c, 0x74, 0x24, 0x4a, 0x64, 0xfd, 0xbf, + 0xcd, 0x91, 0xd4, 0xc3, 0xb4, 0x07, 0x9f, 0x94, 0x1a, 0x62, 0xee, 0x84, 0x6a, 0x08, 0xe3, 0xc7, + 0xf2, 0x30, 0xdf, 0xab, 0xcb, 0xfa, 0xdc, 0x46, 0x3f, 0x0d, 0xe9, 0x5d, 0x48, 0xdc, 0x4a, 0x4b, + 0x34, 0xb9, 0x17, 0x2d, 0x42, 0xf6, 0x66, 0x23, 0x6e, 0xa9, 0xb3, 0x49, 0x82, 0x2d, 0xbf, 0x45, + 0x6e, 0xc2, 0xb8, 0xd2, 0xc1, 0xb8, 0xdf, 0xf7, 0x1a, 0x0e, 0x13, 0x76, 0xe2, 0x3e, 0x3f, 0x0d, + 0xe2, 0xb8, 0x91, 0xb7, 0x58, 0xfe, 0x8b, 0x94, 0x78, 0x90, 0x84, 0x11, 0x6e, 0x07, 0x13, 0x04, + 0x1e, 0x21, 0x80, 0x67, 0x0b, 0xdf, 0xa6, 0x4d, 0xfc, 0xdb, 0xf8, 0xc5, 0x09, 0x2e, 0x35, 0xa8, + 0x77, 0xce, 0x5e, 0x16, 0xf2, 0x89, 0xbb, 0x68, 0xfe, 0x24, 0x77, 0xd1, 0xc2, 0xf1, 0x77, 0xd1, + 0xa1, 0xe3, 0xee, 0xa2, 0x89, 0xcb, 0xe2, 0xf0, 0x09, 0x2f, 0x8b, 0xa3, 0x27, 0xba, 0x2c, 0x6a, + 0xf7, 0xd8, 0xe2, 0x71, 0xf7, 0xd8, 0x3f, 0xbb, 0x5a, 0x3e, 0xab, 0x57, 0xcb, 0x2c, 0xb1, 0xf2, + 0x44, 0x57, 0xcb, 0xd4, 0xcd, 0x70, 0xe6, 0xe9, 0xdc, 0x0c, 0xc9, 0x53, 0xbb, 0x19, 0xce, 0x7e, + 0xdc, 0x9b, 0xe1, 0xdc, 0xd3, 0xbc, 0x19, 0x9e, 0xfa, 0xd3, 0x78, 0x33, 0x3c, 0xfd, 0x1f, 0xe6, + 0x66, 0x78, 0x03, 0x8a, 0x35, 0x2f, 0x08, 0x6f, 0x79, 0x7e, 0x1b, 0x2f, 0xa7, 0x13, 0x42, 0x11, + 0xef, 0x05, 0x3c, 0xfd, 0xbb, 0x26, 0x9d, 0x09, 0x44, 0xb2, 0x24, 0x27, 0x9c, 0xbc, 0x8a, 0xcd, + 0xc7, 0x6f, 0x21, 0x62, 0xa6, 0x88, 0x1b, 0x59, 0x7a, 0xbe, 0x09, 0x92, 0x3b, 0x43, 0xc5, 0x91, + 0xd2, 0xe8, 0x9d, 0xa1, 0x62, 0xa9, 0x34, 0x33, 0xc0, 0xd5, 0xf2, 0xcf, 0x41, 0x29, 0x29, 0xed, + 0x1e, 0x1f, 0x63, 0xfe, 0xa9, 0x45, 0x6b, 0x65, 0xb2, 0x78, 0x52, 0xda, 0x24, 0xd7, 0x00, 0x6a, + 0xbe, 0xf3, 0xc8, 0x0e, 0xe9, 0x5d, 0x69, 0xec, 0x29, 0x92, 0x2a, 0x70, 0x28, 0x9b, 0xa0, 0xa6, + 0x82, 0x12, 0x5d, 0xb4, 0xf2, 0x59, 0x17, 0x2d, 0xe3, 0x47, 0xf3, 0x30, 0xc3, 0xc3, 0x14, 0x3e, + 0xfb, 0x2f, 0xf5, 0xef, 0x6a, 0xd7, 0xe7, 0xe7, 0xe2, 0x54, 0x31, 0x6a, 0xeb, 0xfa, 0xbc, 0xd5, + 0x7f, 0x05, 0x4e, 0xa5, 0xba, 0x02, 0xaf, 0xd0, 0x2b, 0x32, 0x40, 0x64, 0xea, 0x12, 0x3d, 0x9f, + 0x5d, 0xc9, 0x83, 0x1b, 0x66, 0x8a, 0xc2, 0xf8, 0xd5, 0xe1, 0x14, 0x7f, 0xf1, 0x6a, 0xaf, 0xbe, + 0xc3, 0xe7, 0x4e, 0xf6, 0x0e, 0x9f, 0x1f, 0xec, 0x1d, 0x3e, 0x21, 0x41, 0x14, 0x06, 0x91, 0x20, + 0xde, 0x87, 0xc9, 0x4d, 0x6a, 0xb7, 0x83, 0x4d, 0x4f, 0xe4, 0x1d, 0xe4, 0xae, 0x45, 0x32, 0xfe, + 0x23, 0x2b, 0x93, 0x37, 0xc0, 0xc8, 0x44, 0x3a, 0x64, 0x04, 0xec, 0x8c, 0xe4, 0x89, 0x08, 0x4d, + 0x9d, 0x83, 0x7a, 0xad, 0x1f, 0xee, 0x73, 0xad, 0xaf, 0xc3, 0x84, 0xa0, 0x8b, 0x03, 0xeb, 0xc7, + 0xf7, 0x4f, 0x56, 0x84, 0x70, 0x59, 0xbb, 0xf4, 0xf1, 0x9d, 0x8a, 0x6a, 0xe7, 0x57, 0x4f, 0x8d, + 0x09, 0xeb, 0x02, 0xf9, 0xd0, 0xc4, 0xba, 0x60, 0x34, 0xee, 0x02, 0xf9, 0x28, 0xc5, 0xbb, 0x40, + 0x41, 0x22, 0x6f, 0xc3, 0x54, 0xa5, 0x56, 0x55, 0xc9, 0x8a, 0xb1, 0x29, 0x80, 0xdd, 0x71, 0x2c, + 0x8d, 0x34, 0x81, 0xdb, 0xef, 0x2a, 0x36, 0xf6, 0x27, 0x74, 0x15, 0x4b, 0x5e, 0x1a, 0xe0, 0xa4, + 0x97, 0x86, 0xdf, 0x98, 0x90, 0xfb, 0xc3, 0x27, 0xfb, 0x38, 0xa3, 0x3f, 0xb7, 0x14, 0x4e, 0xf8, + 0xdc, 0x32, 0x74, 0x9c, 0x98, 0xaa, 0x48, 0xc3, 0x23, 0x1f, 0xfb, 0xe9, 0x64, 0xf4, 0x84, 0xf2, + 0x6d, 0x62, 0xf1, 0x15, 0x07, 0x59, 0x7c, 0x99, 0x32, 0xf1, 0xd8, 0xc7, 0x97, 0x89, 0xe1, 0xc4, + 0x32, 0x71, 0x3d, 0xf6, 0xdd, 0x1f, 0x3f, 0xd6, 0x25, 0xea, 0xbc, 0xd0, 0x5b, 0xcc, 0x64, 0x47, + 0xa1, 0x8c, 0xbc, 0xf8, 0xbf, 0xaf, 0x04, 0xed, 0xaf, 0x65, 0x0b, 0xda, 0xfd, 0x0f, 0xa0, 0x3f, + 0x13, 0xb5, 0xff, 0x4c, 0xd4, 0xfe, 0x13, 0x11, 0xb5, 0xef, 0x03, 0xb1, 0xbb, 0xe1, 0x1e, 0x75, + 0x43, 0xa7, 0x81, 0x91, 0x90, 0xd9, 0x10, 0xa3, 0xd0, 0x2d, 0xd6, 0x48, 0xba, 0x54, 0x5d, 0x23, + 0x5a, 0x29, 0x9b, 0x01, 0x3c, 0x7a, 0xec, 0xc0, 0x22, 0xb4, 0x8f, 0x2b, 0xea, 0xa1, 0xed, 0xbb, + 0x78, 0x20, 0x5d, 0x83, 0x51, 0x19, 0x79, 0x37, 0x17, 0xab, 0xb9, 0xd3, 0x21, 0x77, 0x25, 0x16, + 0x59, 0x84, 0xa2, 0x24, 0x56, 0xd3, 0x97, 0x3d, 0x16, 0x30, 0x2d, 0xa8, 0xa9, 0x80, 0x19, 0xff, + 0xf9, 0x90, 0xdc, 0xb5, 0xd9, 0x07, 0xd7, 0x6c, 0xdf, 0x6e, 0x63, 0xf6, 0xd4, 0x68, 0x51, 0x29, + 0x02, 0x7c, 0x62, 0x1d, 0x26, 0xbc, 0x59, 0x74, 0x92, 0x8f, 0x14, 0x3a, 0x39, 0x4e, 0x50, 0x5f, + 0x18, 0x20, 0x41, 0xfd, 0x1b, 0x5a, 0x76, 0xf7, 0xa1, 0x38, 0x9d, 0x30, 0xdb, 0xc9, 0xfa, 0xe7, + 0x75, 0xbf, 0xa9, 0xa6, 0x61, 0x1f, 0x8e, 0x03, 0xd9, 0x21, 0x65, 0x9f, 0x04, 0xec, 0xd1, 0x8d, + 0x64, 0xe4, 0x24, 0x41, 0xc9, 0x47, 0xff, 0x83, 0x06, 0x25, 0x5f, 0x05, 0x10, 0xa7, 0x6b, 0x6c, + 0x0d, 0xf1, 0x32, 0x6e, 0x3e, 0xc2, 0x32, 0x3f, 0x0c, 0x5b, 0x3d, 0x92, 0x26, 0x29, 0x84, 0xc6, + 0x3f, 0x23, 0x30, 0x53, 0xaf, 0xdf, 0x5f, 0x71, 0xec, 0x5d, 0xd7, 0x0b, 0x42, 0xa7, 0x51, 0x75, + 0x77, 0x3c, 0x26, 0x8e, 0x47, 0x27, 0x80, 0x12, 0x4e, 0x3a, 0xde, 0xfd, 0xa3, 0x62, 0x76, 0xdd, + 0x5b, 0xf5, 0x7d, 0xa9, 0x10, 0xe5, 0xd7, 0x3d, 0xca, 0x00, 0x26, 0x87, 0x33, 0x89, 0xb7, 0xde, + 0xc5, 0x60, 0x2e, 0xc2, 0xe4, 0x04, 0x25, 0xde, 0x80, 0x83, 0x4c, 0x59, 0x46, 0x68, 0x7a, 0xc2, + 0x8a, 0x1b, 0xd0, 0x19, 0x2d, 0xb4, 0x79, 0x5c, 0xcc, 0xd7, 0xae, 0x90, 0x3f, 0x70, 0xd7, 0xee, + 0x20, 0x5c, 0x35, 0x9d, 0x4c, 0xad, 0x81, 0x03, 0x38, 0xa5, 0xb9, 0xf9, 0x0f, 0xfa, 0xc2, 0xf3, + 0xaa, 0x90, 0xb0, 0x0d, 0x34, 0x4f, 0xcf, 0x78, 0xe6, 0x51, 0xd3, 0xa1, 0x66, 0xd6, 0x40, 0x7e, + 0x34, 0x07, 0xe7, 0x33, 0x4b, 0xa2, 0xd5, 0x3d, 0xae, 0x85, 0x97, 0x57, 0x36, 0x0d, 0x9e, 0xf8, + 0xb5, 0x57, 0xd5, 0x56, 0xc6, 0x56, 0xd0, 0xbf, 0x26, 0xf2, 0xeb, 0x39, 0x38, 0xa3, 0x61, 0x44, + 0xbb, 0x65, 0x10, 0x45, 0xc0, 0xc9, 0x9c, 0xd7, 0x1f, 0x3e, 0x9d, 0x79, 0xfd, 0xa2, 0xde, 0x96, + 0x78, 0xb7, 0x54, 0xdb, 0xd0, 0xeb, 0x0b, 0xc9, 0x23, 0x98, 0xc1, 0x22, 0xf9, 0xda, 0xc4, 0xe6, + 0xac, 0x78, 0xa4, 0x9a, 0x8b, 0x3f, 0x9b, 0x87, 0xae, 0x60, 0xb2, 0xf5, 0xd2, 0xe2, 0x77, 0x0f, + 0xcb, 0x93, 0x1a, 0xba, 0x0c, 0xd8, 0x6e, 0xc5, 0x4f, 0x56, 0x8e, 0xbb, 0xe3, 0xa9, 0xfb, 0x7e, + 0xaa, 0x0a, 0xf2, 0x8f, 0x73, 0xfc, 0xfd, 0x80, 0x37, 0xe3, 0x96, 0xef, 0xb5, 0xa3, 0x72, 0x69, + 0x83, 0xdb, 0xa3, 0xdb, 0x5a, 0x4f, 0xa7, 0xdb, 0x5e, 0xc6, 0x4f, 0xe6, 0x7b, 0x82, 0xb5, 0xe3, + 0x7b, 0xed, 0xf8, 0xf3, 0xd5, 0x8e, 0xeb, 0xf9, 0x91, 0xe4, 0x2f, 0xe6, 0xe0, 0xac, 0xa6, 0xf6, + 0x54, 0x33, 0xf1, 0x88, 0x00, 0x21, 0xb3, 0x51, 0xe8, 0xa0, 0xb8, 0x68, 0xe9, 0xaa, 0x98, 0xff, + 0x17, 0xf1, 0x0b, 0x94, 0x48, 0xb5, 0x0c, 0xc9, 0x6a, 0x73, 0x2c, 0xe5, 0x13, 0x7a, 0xd7, 0x42, + 0x1c, 0x98, 0x41, 0xa3, 0x1e, 0xcd, 0x56, 0x7c, 0xae, 0xb7, 0xad, 0x78, 0x94, 0x96, 0x0d, 0x73, + 0x66, 0xf4, 0x36, 0x18, 0x4f, 0x73, 0x25, 0x3f, 0x04, 0x67, 0x53, 0xc0, 0x68, 0xb5, 0x9d, 0xea, + 0xb9, 0xda, 0x3e, 0x7d, 0x74, 0x58, 0x7e, 0x25, 0xab, 0xb6, 0xac, 0x95, 0xd6, 0xbb, 0x06, 0x62, + 0x03, 0xc4, 0x85, 0x42, 0xfa, 0xc9, 0x9e, 0xa0, 0x9f, 0x16, 0xf3, 0x43, 0xc1, 0x67, 0x7b, 0xb9, + 0xf2, 0x0d, 0xea, 0x91, 0x17, 0x23, 0x11, 0x0a, 0x13, 0x4a, 0xbe, 0x90, 0x03, 0x61, 0xe7, 0xd2, + 0xa3, 0x92, 0xef, 0x1e, 0x96, 0x35, 0x6c, 0x76, 0x07, 0x52, 0x13, 0x91, 0x68, 0xc2, 0xa6, 0x8a, + 0x48, 0x7e, 0x2d, 0x07, 0x73, 0x0c, 0x10, 0x4f, 0x2a, 0xd1, 0xa8, 0xf9, 0x7e, 0xb3, 0x7e, 0xef, + 0xe9, 0xcc, 0xfa, 0x17, 0xf0, 0x1b, 0xd5, 0x59, 0x9f, 0xea, 0x92, 0xcc, 0x8f, 0xc3, 0xd9, 0xae, + 0xd9, 0x8f, 0x69, 0xb3, 0xfd, 0xec, 0x00, 0xb3, 0x9d, 0x0f, 0xc0, 0xf1, 0xb3, 0xbd, 0x67, 0x2d, + 0x64, 0x13, 0x26, 0xc4, 0xf5, 0x87, 0x77, 0xd8, 0xf3, 0x5a, 0xe4, 0x72, 0xb5, 0x88, 0xdf, 0x49, + 0x45, 0x3a, 0x95, 0x54, 0x0b, 0x35, 0x2e, 0xc4, 0x85, 0x59, 0xfe, 0x5b, 0xd7, 0x4f, 0x95, 0x7b, + 0xea, 0xa7, 0x2e, 0x89, 0x16, 0x5d, 0x10, 0xfc, 0x13, 0x6a, 0x2a, 0x35, 0xe2, 0x58, 0x06, 0x63, + 0xd2, 0x01, 0xa2, 0x81, 0xf9, 0xa2, 0xbd, 0xd0, 0x5f, 0x2b, 0xf5, 0x8a, 0xa8, 0xb3, 0x9c, 0xac, + 0x33, 0xb9, 0x72, 0x33, 0x78, 0x13, 0x1b, 0xa6, 0x05, 0xd4, 0xdb, 0xa7, 0x7c, 0x87, 0x7f, 0x41, + 0x8b, 0xf9, 0x96, 0x28, 0xe5, 0x77, 0x38, 0x59, 0x13, 0xc6, 0xe4, 0x4b, 0x6c, 0xe8, 0x49, 0x7e, + 0xe4, 0x3e, 0xcc, 0x54, 0x3a, 0x9d, 0x96, 0x43, 0x9b, 0xd8, 0x4a, 0xb3, 0xcb, 0xda, 0x64, 0xc4, + 0x09, 0x31, 0x6d, 0x5e, 0x28, 0x2e, 0x96, 0x7e, 0x37, 0xb1, 0xdd, 0xa4, 0x68, 0x8d, 0x1f, 0xc9, + 0xa5, 0x3e, 0x9a, 0xbc, 0x06, 0x63, 0xf8, 0x43, 0x09, 0x23, 0x84, 0x5a, 0x1a, 0xfe, 0x89, 0xa8, + 0xff, 0x89, 0x11, 0x98, 0xb0, 0xa4, 0x86, 0x12, 0x2d, 0x70, 0x61, 0x49, 0xa8, 0x12, 0x62, 0xe5, + 0x41, 0x59, 0xfa, 0xf0, 0x14, 0x62, 0xa1, 0x0b, 0x7d, 0x78, 0x84, 0xe7, 0x8e, 0xf1, 0x5f, 0xe5, + 0xf5, 0x69, 0x47, 0x2e, 0x29, 0x72, 0xbb, 0x12, 0xcc, 0x54, 0xca, 0xed, 0x8a, 0xb4, 0xfe, 0xcb, + 0x39, 0x98, 0xbd, 0xaf, 0xa4, 0x69, 0xde, 0xf4, 0x70, 0x5c, 0xfa, 0x27, 0x24, 0x7e, 0x5a, 0x39, + 0x52, 0xd5, 0xfc, 0xd0, 0x6c, 0xa6, 0xe0, 0x94, 0x31, 0xb3, 0xbe, 0x07, 0xfd, 0x3b, 0xf1, 0xc3, + 0x94, 0x54, 0xb5, 0x1c, 0x9d, 0xc3, 0x4f, 0x98, 0x5c, 0xc5, 0xf8, 0xf1, 0x3c, 0x8c, 0x2b, 0x2b, + 0x86, 0x7c, 0x16, 0x26, 0xd4, 0x6a, 0x55, 0x15, 0x9f, 0xfa, 0x95, 0xa6, 0x86, 0x85, 0x3a, 0x3e, + 0x6a, 0xb7, 0x35, 0x1d, 0x1f, 0x5b, 0x17, 0x08, 0x3d, 0xe1, 0x4d, 0xe8, 0xbd, 0x8c, 0x9b, 0x10, + 0xce, 0x72, 0x45, 0xa7, 0xd3, 0xf7, 0x3e, 0xf4, 0x76, 0xfa, 0x3e, 0x84, 0xea, 0x25, 0x85, 0xbe, + 0xf7, 0xad, 0xc8, 0xf8, 0xa9, 0x1c, 0x94, 0x92, 0x6b, 0xfa, 0x13, 0xe9, 0x95, 0x13, 0x3c, 0x08, + 0x7d, 0x2b, 0x1f, 0xe5, 0x16, 0x92, 0x4e, 0xee, 0xcf, 0xaa, 0xa9, 0xe3, 0x3b, 0xda, 0x5b, 0xcd, + 0x39, 0x3d, 0x5e, 0xa3, 0x1a, 0x1e, 0x26, 0x3b, 0x48, 0xeb, 0xd0, 0xb7, 0x7f, 0xa1, 0xfc, 0x29, + 0xe3, 0x8b, 0x30, 0x97, 0xec, 0x0e, 0x7c, 0xaf, 0xa9, 0xc0, 0xb4, 0x0e, 0x4f, 0x66, 0x26, 0x4b, + 0x52, 0x99, 0x49, 0x7c, 0xe3, 0xf7, 0xf2, 0x49, 0xde, 0xc2, 0xec, 0x91, 0xed, 0x51, 0xaa, 0xa1, + 0x8c, 0xd8, 0xa3, 0x38, 0xc8, 0x94, 0x65, 0x27, 0xc9, 0x2e, 0x18, 0xb9, 0x6a, 0x17, 0xb2, 0x5d, + 0xb5, 0xc9, 0xcd, 0x84, 0x0d, 0xb7, 0x12, 0x57, 0xec, 0x31, 0xdd, 0xb6, 0x62, 0x3b, 0xee, 0x94, + 0xe9, 0xf6, 0x9c, 0x16, 0x24, 0x5f, 0xd2, 0x0f, 0xc7, 0xda, 0xf5, 0x10, 0x0b, 0x38, 0x71, 0x26, + 0x32, 0x59, 0x83, 0x51, 0xf6, 0x99, 0x1b, 0x76, 0x47, 0x3c, 0xc3, 0x90, 0x28, 0x70, 0x43, 0x2b, + 0xba, 0x1f, 0x2a, 0xb1, 0x1b, 0x5a, 0x94, 0x49, 0x08, 0xea, 0xc4, 0x12, 0x88, 0xc6, 0xff, 0x9d, + 0x63, 0xeb, 0xbf, 0xb1, 0xff, 0x7d, 0x96, 0x56, 0x90, 0x35, 0xa9, 0x8f, 0x55, 0xee, 0xbf, 0xce, + 0xf3, 0x6c, 0x51, 0x62, 0xfa, 0xbc, 0x01, 0x23, 0x9b, 0xb6, 0xbf, 0x4b, 0x43, 0x91, 0x47, 0x49, + 0xe5, 0xc2, 0x0b, 0xe2, 0xa8, 0x67, 0x21, 0xfe, 0x36, 0x05, 0x81, 0xaa, 0x3a, 0xcb, 0x0f, 0xa4, + 0x3a, 0x53, 0x34, 0xf7, 0x85, 0xa7, 0xa6, 0xb9, 0xff, 0x81, 0x28, 0x31, 0x54, 0x25, 0x1c, 0x20, + 0x06, 0xfb, 0x85, 0x64, 0x1e, 0xb6, 0x54, 0xb4, 0xfc, 0x98, 0x1d, 0xb9, 0xa9, 0x66, 0x76, 0x53, + 0x7c, 0x86, 0x8f, 0xc9, 0xe1, 0x66, 0x7c, 0x67, 0x88, 0xf7, 0xb1, 0xe8, 0xa8, 0x8b, 0x5a, 0x64, + 0x04, 0x5c, 0x27, 0x09, 0xad, 0x26, 0x8f, 0x91, 0x70, 0x11, 0x86, 0xd8, 0xdc, 0x14, 0xbd, 0x89, + 0x78, 0x6c, 0xfe, 0xaa, 0x78, 0xac, 0x9c, 0xad, 0x65, 0x3c, 0x93, 0xd4, 0xf4, 0x9f, 0x78, 0x6c, + 0xa9, 0x6b, 0x19, 0x31, 0x58, 0x0b, 0xa2, 0xbc, 0x27, 0x6a, 0x0b, 0xda, 0x3b, 0x76, 0x3a, 0xc1, + 0xa2, 0x92, 0x6c, 0x69, 0x15, 0xa6, 0x1e, 0x3a, 0x6e, 0xd3, 0x7b, 0x1c, 0xac, 0xd0, 0x60, 0x3f, + 0xf4, 0x3a, 0xc2, 0x12, 0x19, 0x35, 0xfc, 0x8f, 0x79, 0x89, 0xd5, 0xe4, 0x45, 0xea, 0x73, 0x88, + 0x4e, 0x44, 0x96, 0x60, 0x52, 0x8b, 0x1c, 0x2c, 0x5e, 0x39, 0x51, 0xc7, 0xa9, 0xc7, 0x1d, 0x56, + 0x75, 0x9c, 0x1a, 0x09, 0x3b, 0xa5, 0xc5, 0xf7, 0x2b, 0x6f, 0x9d, 0xa9, 0x6f, 0x17, 0x38, 0xe4, + 0x06, 0x14, 0x79, 0x78, 0x99, 0xea, 0x8a, 0xfa, 0x3c, 0x15, 0x20, 0x2c, 0x11, 0x9e, 0x49, 0x22, + 0x92, 0x65, 0x98, 0x5c, 0xf2, 0xc2, 0xaa, 0x1b, 0x84, 0xb6, 0xdb, 0xa0, 0x51, 0x9c, 0x64, 0x6c, + 0xec, 0xb6, 0x17, 0x5a, 0x8e, 0x28, 0xd1, 0xe9, 0x75, 0x1a, 0xd6, 0xd5, 0x77, 0x3c, 0xc7, 0xe5, + 0x5b, 0xe7, 0x78, 0xdc, 0xd5, 0x1f, 0x7a, 0x8e, 0x9b, 0x0a, 0x4d, 0x1c, 0xa3, 0xc6, 0xb1, 0x4c, + 0xb8, 0xbf, 0xa3, 0x39, 0x74, 0xcf, 0x6b, 0x52, 0xe3, 0x33, 0x50, 0x12, 0x3b, 0x5e, 0x94, 0x4d, + 0x16, 0x2d, 0x27, 0xaa, 0x2b, 0xa6, 0xba, 0x4b, 0x35, 0x9c, 0xa6, 0x6f, 0x22, 0x14, 0x7d, 0x0e, + 0xef, 0xd1, 0xf0, 0xb1, 0xe7, 0xef, 0x9b, 0x34, 0x08, 0x7d, 0x87, 0x27, 0xa7, 0xc5, 0x75, 0xfe, + 0x59, 0xf2, 0x36, 0x0c, 0xa3, 0x6d, 0x6e, 0xe2, 0xe0, 0x49, 0xd6, 0xb1, 0x34, 0x29, 0xd6, 0xc7, + 0x30, 0x1a, 0xfa, 0x9a, 0x9c, 0x88, 0xbc, 0x01, 0x43, 0x2b, 0xd4, 0x3d, 0x48, 0xe4, 0xba, 0x4c, + 0x11, 0x47, 0xfb, 0x4d, 0x93, 0xba, 0x07, 0x26, 0x92, 0x18, 0x3f, 0x95, 0x87, 0x53, 0x19, 0x9f, + 0xf5, 0xe0, 0xb3, 0xcf, 0xe8, 0xa6, 0xbb, 0xa4, 0x6d, 0xba, 0xf2, 0xc5, 0xbc, 0x67, 0xc7, 0x67, + 0xee, 0xc1, 0x7f, 0x3d, 0x07, 0x67, 0xf4, 0x95, 0x22, 0x8c, 0xf1, 0x1f, 0xdc, 0x20, 0x6f, 0xc1, + 0xc8, 0x1a, 0xb5, 0x9b, 0x54, 0x26, 0xb6, 0x4b, 0xa6, 0x8f, 0xe6, 0x85, 0x9c, 0x6d, 0xec, 0x28, + 0xcd, 0xa1, 0x64, 0x45, 0x7c, 0x1c, 0xbf, 0x1d, 0x18, 0x32, 0xa0, 0x4e, 0x56, 0x55, 0x7d, 0xec, + 0x4e, 0xbe, 0x9b, 0x83, 0x73, 0x7d, 0x68, 0xd8, 0xc0, 0xb1, 0xa1, 0x57, 0x07, 0x0e, 0x0f, 0x6c, + 0x84, 0x92, 0x77, 0x61, 0x7a, 0x53, 0xdc, 0x2e, 0xe4, 0x70, 0xe4, 0xe3, 0x85, 0x2b, 0x2f, 0x1e, + 0xd2, 0x32, 0xca, 0x4c, 0x22, 0x6b, 0x91, 0x9e, 0x0a, 0x7d, 0x23, 0x3d, 0xa9, 0x81, 0x93, 0x86, + 0x06, 0x0d, 0x9c, 0xf4, 0x45, 0x98, 0xd3, 0xdb, 0x26, 0xe2, 0x57, 0xc7, 0x61, 0xa3, 0x72, 0xbd, + 0xc3, 0x46, 0xf5, 0x8d, 0x92, 0x6b, 0xfc, 0x78, 0x0e, 0x4a, 0x3a, 0xef, 0x8f, 0x3b, 0x9e, 0xef, + 0x68, 0xe3, 0x79, 0x2e, 0x7b, 0x3c, 0x7b, 0x0f, 0xe4, 0xff, 0x91, 0x4b, 0x36, 0x76, 0xa0, 0x11, + 0x34, 0x60, 0x64, 0xc5, 0x6b, 0xdb, 0x8e, 0x1c, 0x38, 0xf4, 0xa4, 0x69, 0x22, 0xc4, 0x14, 0x25, + 0x83, 0x45, 0xd9, 0xba, 0x00, 0xc3, 0xf7, 0x3c, 0xb7, 0xb2, 0x22, 0x2c, 0x8a, 0x91, 0x8f, 0xeb, + 0xb9, 0x96, 0xdd, 0x34, 0x79, 0x01, 0x59, 0x07, 0xa8, 0x37, 0x7c, 0x4a, 0xdd, 0xba, 0xf3, 0x83, + 0x34, 0x21, 0xc8, 0xb0, 0x1e, 0x6a, 0x75, 0x71, 0x63, 0xe1, 0xef, 0xb8, 0x88, 0x68, 0x05, 0xce, + 0x0f, 0xaa, 0x1b, 0xbf, 0x42, 0x8f, 0xeb, 0x4a, 0x04, 0x22, 0x4c, 0x8c, 0xc3, 0xf5, 0x4f, 0x62, + 0x5d, 0x65, 0x56, 0x85, 0x3d, 0x7c, 0x3d, 0x73, 0x38, 0x7e, 0x37, 0x07, 0xe7, 0xfa, 0xd0, 0x3c, + 0x85, 0x51, 0xf9, 0x93, 0xee, 0x70, 0x0a, 0x10, 0x13, 0x61, 0x5a, 0x72, 0xa7, 0x19, 0xf2, 0x64, + 0x95, 0x93, 0x22, 0x2d, 0x39, 0x03, 0x68, 0x69, 0xc9, 0x19, 0x80, 0x1d, 0xea, 0x6b, 0xd4, 0xd9, + 0xdd, 0xe3, 0x06, 0x63, 0x93, 0x7c, 0x6f, 0xd8, 0x43, 0x88, 0x7a, 0xa8, 0x73, 0x1c, 0xe3, 0x5f, + 0x8c, 0xc0, 0x59, 0x93, 0xee, 0x3a, 0xec, 0xda, 0xb3, 0x15, 0x38, 0xee, 0xae, 0x16, 0x78, 0xca, + 0x48, 0xac, 0x5c, 0x91, 0xa5, 0x85, 0x41, 0xa2, 0x99, 0x78, 0x19, 0x8a, 0xec, 0x58, 0x55, 0x16, + 0x2f, 0x3e, 0xa1, 0xb9, 0x5e, 0x93, 0x8a, 0xc8, 0xe6, 0xb2, 0x98, 0xbc, 0x2a, 0xa4, 0x30, 0x25, + 0x8f, 0x16, 0x93, 0xc2, 0xbe, 0x77, 0x58, 0x06, 0x9e, 0x94, 0x9c, 0x95, 0x0a, 0x49, 0x2c, 0xba, + 0x2a, 0x0d, 0xf5, 0xb8, 0x2a, 0x6d, 0xc0, 0x5c, 0xa5, 0xc9, 0x4f, 0x47, 0xbb, 0x55, 0xf3, 0x1d, + 0xb7, 0xe1, 0x74, 0xec, 0x96, 0xbc, 0xfe, 0x63, 0x2f, 0xdb, 0x51, 0xb9, 0xd5, 0x89, 0x10, 0xcc, + 0x4c, 0x32, 0xd6, 0x8c, 0x95, 0x7b, 0x75, 0x8c, 0x6a, 0x24, 0x5e, 0x47, 0xb1, 0x19, 0x4d, 0x37, + 0xc0, 0x56, 0x04, 0x66, 0x54, 0x8c, 0x97, 0x34, 0x7c, 0x0b, 0xdf, 0x5c, 0xaf, 0xdf, 0x15, 0x99, + 0xfe, 0x64, 0x9a, 0x0f, 0x6e, 0xe5, 0x10, 0xb6, 0x02, 0x34, 0xce, 0xd4, 0xf0, 0x62, 0xba, 0x7a, + 0x7d, 0x8d, 0xd1, 0x15, 0x53, 0x74, 0x41, 0xb0, 0xa7, 0xd2, 0x71, 0x3c, 0x72, 0x8d, 0x4d, 0x85, + 0xb6, 0x17, 0x52, 0x9c, 0xc2, 0x63, 0xf1, 0x95, 0xce, 0x47, 0x28, 0xbf, 0xd2, 0x29, 0x28, 0xe4, + 0x6d, 0x98, 0x5d, 0x5d, 0x5e, 0x94, 0x3a, 0xed, 0x15, 0xaf, 0xd1, 0x45, 0xab, 0x04, 0xc0, 0xfa, + 0x70, 0x0c, 0x69, 0x63, 0x91, 0xed, 0x26, 0x59, 0x68, 0xe4, 0x22, 0x8c, 0x56, 0x57, 0x54, 0x59, + 0x4b, 0xe4, 0xb2, 0x13, 0xa6, 0x56, 0xb2, 0x90, 0xdc, 0x8f, 0xef, 0x1c, 0x13, 0xc7, 0x5e, 0x0e, + 0xce, 0x0e, 0x70, 0xdf, 0x78, 0x23, 0x29, 0x2b, 0x2a, 0x81, 0xe5, 0x13, 0xb2, 0x62, 0x52, 0x42, + 0xfc, 0x3c, 0x92, 0xde, 0xa6, 0x2e, 0xf5, 0xe3, 0x80, 0xf2, 0xc3, 0xbc, 0x6f, 0x19, 0xe9, 0x6e, + 0x54, 0x62, 0xea, 0x88, 0xc4, 0x84, 0x53, 0x35, 0x9f, 0x3e, 0x72, 0xbc, 0x6e, 0xa0, 0x57, 0x3e, + 0x1d, 0xcb, 0xd3, 0x1d, 0x81, 0x60, 0x25, 0xbf, 0x22, 0x9b, 0x54, 0xe4, 0xee, 0xe3, 0x19, 0x77, + 0x97, 0xbd, 0x26, 0x0d, 0xf8, 0x0e, 0xf4, 0x7d, 0x94, 0xbb, 0x4f, 0x69, 0x5b, 0x9f, 0x5d, 0xf9, + 0x3f, 0xc3, 0xdc, 0x7d, 0x29, 0x5c, 0xf2, 0x79, 0x18, 0xc6, 0x9f, 0x42, 0x62, 0x9e, 0xcd, 0x60, + 0x1b, 0x4b, 0xcb, 0x0d, 0x86, 0x69, 0x72, 0x02, 0x52, 0x85, 0x51, 0x71, 0x17, 0x3c, 0x49, 0x06, + 0x2a, 0x71, 0xa9, 0xe4, 0xb3, 0x4d, 0xd0, 0x1b, 0x4d, 0x98, 0x50, 0x2b, 0x64, 0xab, 0x6c, 0xcd, + 0x0e, 0xf6, 0x68, 0x93, 0xfd, 0x12, 0xc9, 0x23, 0x71, 0x95, 0xed, 0x21, 0xd4, 0x62, 0xdf, 0x61, + 0x2a, 0x28, 0xec, 0x9c, 0xae, 0x06, 0x5b, 0x81, 0xf8, 0x14, 0xa1, 0x1d, 0x72, 0x50, 0xd3, 0xd8, + 0x34, 0x45, 0x91, 0xf1, 0x03, 0x30, 0x77, 0xaf, 0xdb, 0x6a, 0xd9, 0xdb, 0x2d, 0x2a, 0x93, 0x0b, + 0x61, 0x16, 0xff, 0x25, 0x18, 0xc6, 0x3f, 0xb0, 0xa2, 0xa9, 0x38, 0xc1, 0xab, 0x82, 0x83, 0xa6, + 0xb6, 0x39, 0x8c, 0x5a, 0xc5, 0x7e, 0x6a, 0x51, 0xab, 0x18, 0xc0, 0xf8, 0x9d, 0x1c, 0xcc, 0x49, + 0x0b, 0x07, 0xdf, 0x6e, 0xec, 0x53, 0x5f, 0x08, 0x5c, 0x17, 0xb5, 0xb9, 0x86, 0x8b, 0x20, 0x31, + 0x8d, 0xf8, 0xac, 0xbb, 0x23, 0x3f, 0x42, 0x17, 0x82, 0xb2, 0x3e, 0xf8, 0xb8, 0x8f, 0x21, 0x6f, + 0xc3, 0xb8, 0x38, 0x72, 0x95, 0xa8, 0xb1, 0xff, 0x3f, 0x7b, 0x5f, 0x1b, 0x23, 0x47, 0x76, 0x1c, + 0xc6, 0x9e, 0x99, 0xdd, 0x9d, 0xad, 0xfd, 0xea, 0x7d, 0x5c, 0x92, 0xcb, 0x25, 0x8f, 0x1f, 0x7d, + 0x77, 0x34, 0x6f, 0x4f, 0xc7, 0x3b, 0xf2, 0x72, 0x77, 0xa2, 0xa4, 0xbb, 0x53, 0xef, 0x4c, 0xef, + 0xee, 0x90, 0xf3, 0xa5, 0xee, 0x59, 0xd2, 0xd4, 0x49, 0x6e, 0x37, 0x67, 0x7a, 0x77, 0xfb, 0x38, + 0x3b, 0x3d, 0x37, 0xdd, 0x73, 0xbc, 0x15, 0x0c, 0x44, 0xb6, 0x10, 0x19, 0x48, 0xe0, 0xd8, 0xb1, + 0x1d, 0x44, 0x30, 0x12, 0x38, 0x40, 0x04, 0xc3, 0x3f, 0x02, 0x24, 0x48, 0xfe, 0x04, 0x11, 0x10, + 0xc4, 0xc8, 0x1f, 0x03, 0x82, 0x82, 0x04, 0x01, 0xfc, 0x43, 0x0e, 0x0e, 0xb6, 0x84, 0x00, 0x81, + 0xe0, 0x7f, 0x46, 0xf2, 0xc3, 0x80, 0x83, 0xe0, 0xd5, 0x7b, 0xaf, 0xfb, 0xf5, 0xc7, 0xcc, 0x2e, + 0xc5, 0x53, 0x12, 0x07, 0xfa, 0x43, 0xee, 0xd4, 0xab, 0xaa, 0x7e, 0xdf, 0xaf, 0x5e, 0x55, 0xbd, + 0x2a, 0x0c, 0x9a, 0xc7, 0xef, 0xb2, 0x69, 0x7f, 0x1b, 0x19, 0x1d, 0xe5, 0xbb, 0x64, 0x53, 0x9e, + 0x57, 0xae, 0xc8, 0x97, 0xef, 0x92, 0xdf, 0x98, 0x32, 0x75, 0xff, 0xfd, 0x42, 0xba, 0x6f, 0xf9, + 0xdc, 0x7d, 0x5b, 0x8e, 0x13, 0xa9, 0xc4, 0x77, 0xd1, 0x38, 0x4e, 0xa4, 0x7c, 0x17, 0x8d, 0x50, + 0xa3, 0x31, 0x29, 0x9c, 0x30, 0x26, 0xef, 0x89, 0x31, 0x29, 0x4e, 0x9e, 0x18, 0x67, 0xa7, 0x8c, + 0x83, 0x15, 0xaf, 0x90, 0xd2, 0xa9, 0x34, 0x41, 0x67, 0x30, 0x21, 0x06, 0x23, 0x49, 0xef, 0xcc, + 0x9c, 0x93, 0xac, 0x5e, 0x9a, 0x39, 0x3d, 0xd3, 0x13, 0xb6, 0xfb, 0x2f, 0xc0, 0xa2, 0x1e, 0x86, + 0x4e, 0xf7, 0xd0, 0xed, 0x55, 0xe9, 0xf6, 0x24, 0x05, 0x82, 0x73, 0x38, 0x5c, 0x36, 0x0b, 0xca, + 0xb8, 0x2c, 0x44, 0xb3, 0x13, 0x70, 0x0f, 0xdd, 0x28, 0x44, 0x33, 0x85, 0x24, 0x43, 0x34, 0x53, + 0x08, 0x79, 0x1d, 0xe6, 0x6a, 0x83, 0x8f, 0x3d, 0xda, 0x27, 0x2c, 0x16, 0x1c, 0xaa, 0xd3, 0x3c, + 0x06, 0x92, 0x37, 0x57, 0x8e, 0x45, 0xee, 0x4a, 0x17, 0xa5, 0xf9, 0x58, 0x61, 0xc1, 0xb4, 0x74, + 0x51, 0x4c, 0x21, 0xf9, 0x12, 0x14, 0xdd, 0x9c, 0xde, 0x86, 0x39, 0xa1, 0x7c, 0x85, 0xf8, 0x04, + 0xe1, 0x94, 0xd9, 0x08, 0x1c, 0x02, 0x19, 0x13, 0xfd, 0x4b, 0x49, 0x30, 0x17, 0xa4, 0x44, 0xff, + 0x52, 0x12, 0xcc, 0x44, 0xa2, 0x7f, 0x29, 0x1d, 0x66, 0xa4, 0xb7, 0x5a, 0x3c, 0x51, 0x6f, 0xf5, + 0x00, 0x16, 0xdb, 0xce, 0x28, 0xf4, 0xa8, 0xdc, 0x33, 0x08, 0x83, 0xf5, 0xa5, 0x84, 0xaa, 0x57, + 0x2a, 0xda, 0xba, 0x22, 0x92, 0xcd, 0x0f, 0x25, 0xfc, 0x64, 0x56, 0xf4, 0x18, 0x9e, 0xef, 0x9f, + 0xbb, 0xfc, 0x3c, 0xfe, 0xb9, 0xd8, 0xa9, 0xa8, 0xde, 0x5b, 0x89, 0xd5, 0x4d, 0x78, 0x11, 0x4a, + 0xe9, 0xf8, 0x22, 0x44, 0xf2, 0x35, 0x58, 0xa4, 0x7f, 0xb7, 0xfd, 0xbe, 0xd7, 0xf5, 0xdc, 0x60, + 0x5d, 0xc5, 0xc6, 0x5d, 0xc9, 0x5d, 0xfd, 0x88, 0x74, 0x6c, 0xb9, 0x21, 0x5b, 0xc0, 0xc8, 0x38, + 0xad, 0xb7, 0x4f, 0x70, 0x23, 0xef, 0xc3, 0x22, 0x9d, 0x7d, 0x8f, 0x9d, 0x80, 0x89, 0xbb, 0xab, + 0xb1, 0x87, 0x75, 0x8f, 0xc3, 0x33, 0x51, 0xd2, 0x65, 0x02, 0x7a, 0xcc, 0xeb, 0x43, 0xb6, 0x41, + 0x12, 0x69, 0xb6, 0x0f, 0x33, 0x9b, 0xa3, 0x40, 0x23, 0x5f, 0x86, 0x45, 0x7d, 0x38, 0x8c, 0x77, + 0x9c, 0xb3, 0x92, 0x96, 0x6f, 0x38, 0xb4, 0x73, 0x77, 0x9d, 0x04, 0x45, 0x7a, 0x63, 0x5e, 0x7b, + 0xa6, 0x8d, 0x99, 0xbc, 0x16, 0xdd, 0x00, 0xce, 0xc5, 0x8a, 0x68, 0x7e, 0x19, 0x4d, 0x5c, 0x27, + 0xd8, 0x65, 0xa0, 0x02, 0x4b, 0x4c, 0x33, 0x2b, 0xa4, 0x99, 0xf3, 0x99, 0xd5, 0x93, 0x23, 0xd4, + 0x24, 0x69, 0x88, 0x01, 0xcb, 0xec, 0x91, 0x7b, 0x9f, 0x87, 0xaf, 0x5f, 0xbf, 0x80, 0xab, 0x16, + 0xb9, 0xb0, 0xb7, 0xf1, 0x7d, 0xcc, 0x6a, 0xe4, 0x24, 0xb8, 0xa4, 0x88, 0xb4, 0x1f, 0x2b, 0x70, + 0x61, 0xc2, 0x88, 0x47, 0xc1, 0xcd, 0x95, 0xe9, 0xc1, 0xcd, 0xe9, 0xce, 0x91, 0xd4, 0xb4, 0x60, + 0xfb, 0xb3, 0x4f, 0xcf, 0x22, 0x79, 0xcb, 0x07, 0xc2, 0x13, 0x87, 0xf1, 0x4f, 0xdf, 0xf3, 0x51, + 0x9b, 0x5c, 0xcc, 0x1e, 0x42, 0x1c, 0x8f, 0x55, 0x8a, 0x85, 0x84, 0xe5, 0x79, 0xc9, 0xa2, 0x61, + 0xfd, 0xd0, 0x4f, 0xac, 0xe0, 0x1c, 0xd6, 0xda, 0xa7, 0x0a, 0x2c, 0x48, 0xeb, 0x90, 0x5c, 0x93, + 0x1e, 0x36, 0xab, 0x2c, 0xb3, 0x9d, 0xc4, 0xa1, 0xc0, 0x4e, 0x22, 0x5c, 0x54, 0x85, 0x93, 0x75, + 0xe6, 0x18, 0xee, 0x4b, 0x0a, 0x00, 0x9f, 0x8a, 0xef, 0x85, 0xe5, 0xe4, 0xeb, 0x00, 0x75, 0x27, + 0x08, 0xf5, 0x6e, 0xe8, 0x7d, 0xec, 0x9e, 0xe2, 0xd0, 0x11, 0x21, 0x31, 0xcf, 0x61, 0x2e, 0x15, + 0x07, 0xc9, 0x52, 0x67, 0x84, 0xc4, 0x50, 0xfb, 0x35, 0x05, 0x60, 0xaf, 0x56, 0xc1, 0x0c, 0x0e, + 0xcf, 0x2b, 0x14, 0xe4, 0x47, 0xc5, 0x16, 0xdc, 0xa7, 0x88, 0x03, 0x7f, 0xa2, 0xc0, 0x72, 0x12, + 0x8d, 0xbc, 0x07, 0x2b, 0x56, 0x77, 0xe4, 0xf7, 0xfb, 0x8f, 0x9d, 0xee, 0x93, 0xba, 0x37, 0x70, + 0x59, 0xa4, 0xe0, 0x19, 0x76, 0x16, 0x05, 0x51, 0x91, 0xdd, 0xa7, 0x65, 0x66, 0x1a, 0x99, 0x7c, + 0x4b, 0x81, 0x25, 0xeb, 0xd0, 0x7f, 0x1a, 0x05, 0xde, 0xe5, 0x03, 0xf2, 0x75, 0xba, 0xb6, 0x83, + 0x43, 0xff, 0x69, 0x9c, 0x16, 0x37, 0xe1, 0xde, 0xfa, 0xee, 0xe9, 0x3c, 0x0f, 0xba, 0x3e, 0xde, + 0x47, 0xc2, 0xe0, 0x56, 0xe2, 0x23, 0x66, 0xf2, 0x9b, 0xda, 0x5f, 0x2b, 0xb0, 0x80, 0x37, 0x97, + 0x7e, 0x1f, 0x65, 0xae, 0xff, 0x9f, 0x72, 0xac, 0x46, 0xed, 0x9a, 0x32, 0xb0, 0x6f, 0xc1, 0x4a, + 0x0a, 0x8d, 0x68, 0x30, 0x6b, 0x61, 0xcc, 0x02, 0x59, 0xe9, 0xc1, 0xa2, 0x18, 0x98, 0xbc, 0x44, + 0x33, 0x24, 0xb2, 0x07, 0xb7, 0xd1, 0x12, 0x7d, 0x07, 0xc0, 0x13, 0x20, 0x71, 0xb3, 0x21, 0xe9, + 0x9a, 0x3c, 0xb8, 0x6d, 0x4a, 0x58, 0x5a, 0x13, 0x66, 0x2d, 0x7f, 0x14, 0x6e, 0x1d, 0xb3, 0xcb, + 0x44, 0xd5, 0x0d, 0xba, 0xb2, 0xa9, 0xd9, 0x43, 0x43, 0x50, 0xd7, 0xe4, 0x45, 0xe4, 0x2a, 0xcc, + 0x6c, 0x7b, 0x6e, 0xbf, 0x27, 0xbb, 0x20, 0xef, 0x53, 0x80, 0xc9, 0xe0, 0xf4, 0xc2, 0x75, 0x3e, + 0x4e, 0x74, 0x14, 0xfb, 0x3a, 0x3f, 0xef, 0xba, 0xa9, 0x24, 0xfa, 0xf7, 0x7a, 0x94, 0x5c, 0x24, + 0xfb, 0xa5, 0x29, 0x5d, 0xfd, 0x2f, 0x15, 0xd8, 0x98, 0x4c, 0x22, 0xbb, 0x4f, 0x2b, 0x53, 0xdc, + 0xa7, 0x5f, 0x4e, 0x9b, 0x46, 0x11, 0x8d, 0x9b, 0x46, 0x63, 0x83, 0x68, 0x15, 0xbd, 0xd7, 0xbb, + 0xae, 0xc8, 0x6e, 0x74, 0x6d, 0x4a, 0x9d, 0x11, 0x91, 0x0d, 0x73, 0x88, 0x34, 0x26, 0xa7, 0xd5, + 0xfe, 0x5d, 0x09, 0x2e, 0x4e, 0xa4, 0x20, 0xbb, 0x52, 0xce, 0xb4, 0xe5, 0x28, 0x5b, 0xd3, 0x44, + 0xfc, 0x5b, 0xf8, 0x2f, 0x3a, 0x28, 0xa6, 0x9f, 0xc4, 0xb5, 0xa2, 0x5c, 0x59, 0x05, 0xe4, 0xf5, + 0xea, 0x89, 0xbc, 0x18, 0x3a, 0x32, 0x83, 0x6c, 0xda, 0x2c, 0x7c, 0x7d, 0xe9, 0x86, 0x8e, 0xd7, + 0x0f, 0xe4, 0x65, 0xd7, 0x63, 0x20, 0x53, 0x94, 0xc5, 0x3e, 0xed, 0xa5, 0x7c, 0x9f, 0x76, 0xed, + 0x7f, 0x29, 0x30, 0x1f, 0x55, 0x9b, 0x6c, 0xc0, 0xf9, 0x8e, 0xa9, 0x57, 0x0c, 0xbb, 0xf3, 0xa8, + 0x6d, 0xd8, 0x7b, 0x4d, 0xab, 0x6d, 0x54, 0x6a, 0xdb, 0x35, 0xa3, 0xaa, 0x9e, 0x21, 0xab, 0xb0, + 0xb4, 0xd7, 0xbc, 0xdf, 0x6c, 0x3d, 0x6c, 0xda, 0x86, 0x69, 0xb6, 0x4c, 0x55, 0x21, 0x4b, 0x30, + 0x6f, 0x6e, 0xe9, 0x15, 0xbb, 0xd9, 0xaa, 0x1a, 0x6a, 0x81, 0xa8, 0xb0, 0x58, 0x69, 0x35, 0x9b, + 0x46, 0xa5, 0x53, 0x7b, 0x50, 0xeb, 0x3c, 0x52, 0x8b, 0x84, 0xc0, 0x32, 0x22, 0xb4, 0xcd, 0x5a, + 0xb3, 0x52, 0x6b, 0xeb, 0x75, 0xb5, 0x44, 0x61, 0x14, 0x5f, 0x82, 0xcd, 0x44, 0x8c, 0xee, 0xef, + 0x6d, 0x19, 0xea, 0x2c, 0x45, 0xa1, 0x7f, 0x49, 0x28, 0x73, 0xf4, 0xf3, 0x88, 0x52, 0xd5, 0x3b, + 0xfa, 0x96, 0x6e, 0x19, 0x6a, 0x99, 0x5c, 0x80, 0xb3, 0x09, 0x90, 0x5d, 0x6f, 0xed, 0xd4, 0x9a, + 0xea, 0x3c, 0x59, 0x03, 0x35, 0x82, 0x55, 0xb7, 0xec, 0x3d, 0xcb, 0x30, 0x55, 0x48, 0x43, 0x9b, + 0x7a, 0xc3, 0x50, 0x17, 0xb4, 0x77, 0xd9, 0x63, 0x45, 0xd6, 0xd5, 0xe4, 0x3c, 0x10, 0xab, 0xa3, + 0x77, 0xf6, 0xac, 0x54, 0xe3, 0x17, 0x60, 0xce, 0xda, 0xab, 0x54, 0x0c, 0xcb, 0x52, 0x15, 0x02, + 0x30, 0xbb, 0xad, 0xd7, 0xea, 0x46, 0x55, 0x2d, 0x68, 0xbf, 0xa5, 0xc0, 0xaa, 0x90, 0x00, 0x85, + 0x21, 0xea, 0x39, 0xd7, 0xe2, 0x7b, 0x89, 0x8b, 0xad, 0x78, 0x79, 0x96, 0xfa, 0xc8, 0x94, 0x65, + 0xf8, 0x8f, 0x15, 0x38, 0x97, 0x8b, 0x4d, 0x1e, 0x81, 0x2a, 0x6a, 0x10, 0xbd, 0x22, 0x55, 0x12, + 0x02, 0xb4, 0xa0, 0x4b, 0xa1, 0x31, 0x55, 0x69, 0x9c, 0xc5, 0x3d, 0xc3, 0xe6, 0xf4, 0x39, 0x46, + 0xb4, 0xef, 0x28, 0x70, 0x61, 0xc2, 0x67, 0x48, 0x05, 0x66, 0xa3, 0x6c, 0x53, 0x53, 0x7c, 0xf4, + 0xd6, 0x7e, 0xf8, 0xe9, 0x55, 0x8e, 0x88, 0x69, 0xaf, 0xf1, 0x2f, 0x73, 0x36, 0x4a, 0x1f, 0x85, + 0x39, 0x9c, 0x58, 0xf7, 0x5d, 0x4c, 0xf5, 0x3c, 0xff, 0x92, 0xfe, 0xd0, 0xda, 0x5a, 0xe0, 0x7d, + 0x57, 0x74, 0x9e, 0x06, 0x98, 0xc4, 0x49, 0xfb, 0x5d, 0x85, 0x0a, 0x77, 0x69, 0x44, 0x2a, 0xf3, + 0xea, 0x41, 0x30, 0x3e, 0x72, 0x4d, 0xbf, 0xef, 0xea, 0x66, 0x93, 0x1f, 0x1b, 0x28, 0xad, 0x3a, + 0x58, 0x80, 0xd7, 0x0a, 0xdb, 0x19, 0x25, 0x82, 0x15, 0x24, 0x68, 0xc8, 0x5d, 0x00, 0xe3, 0x93, + 0xd0, 0x1d, 0x0d, 0x9c, 0x7e, 0x14, 0x76, 0x86, 0x05, 0xf4, 0xe2, 0xd0, 0xa4, 0xbc, 0x2d, 0x21, + 0x6b, 0xdf, 0x56, 0x60, 0x91, 0x5f, 0x9a, 0xf4, 0xbe, 0x3b, 0x0a, 0x9f, 0x6f, 0x7a, 0xdd, 0x4d, + 0x4c, 0xaf, 0xe8, 0x49, 0x8a, 0xc4, 0x9f, 0x16, 0xe7, 0xce, 0xac, 0xff, 0xa8, 0x80, 0x9a, 0x46, + 0x24, 0xef, 0x41, 0xd9, 0x72, 0x3f, 0x76, 0x47, 0x5e, 0x78, 0xcc, 0x37, 0x4a, 0x91, 0x97, 0x93, + 0xe1, 0xf0, 0x32, 0x36, 0x1f, 0x02, 0xfe, 0xcb, 0x8c, 0x68, 0x4e, 0xbb, 0xdf, 0x4b, 0x6a, 0x8f, + 0xe2, 0x67, 0xa5, 0xf6, 0xd0, 0xfe, 0xac, 0x00, 0x17, 0x76, 0xdc, 0x50, 0x6e, 0x53, 0xe4, 0x3b, + 0xf1, 0xc6, 0xe9, 0xda, 0x25, 0xb5, 0x64, 0x1d, 0xe6, 0xb0, 0x48, 0x8c, 0xaf, 0x29, 0x7e, 0x92, + 0xad, 0x68, 0x5e, 0x17, 0x13, 0x89, 0xff, 0x26, 0x7c, 0xfb, 0x96, 0x94, 0x0a, 0x2c, 0x9a, 0xd6, + 0x37, 0x60, 0x19, 0xb3, 0x50, 0x8c, 0xe9, 0x72, 0x70, 0x7b, 0x5c, 0xfd, 0x53, 0x36, 0x53, 0x50, + 0xb2, 0x09, 0x2a, 0x85, 0xe8, 0xdd, 0x27, 0x03, 0xff, 0x69, 0xdf, 0xed, 0x1d, 0xb8, 0x3d, 0x3c, + 0xd6, 0xcb, 0x66, 0x06, 0x2e, 0x78, 0xee, 0x0d, 0xd8, 0xd5, 0xcd, 0xed, 0xa1, 0x8e, 0x86, 0xf3, + 0x8c, 0xa1, 0x1b, 0x77, 0x61, 0xe1, 0xa7, 0x4c, 0xeb, 0xa7, 0xfd, 0xa9, 0x02, 0x6b, 0xd8, 0x38, + 0xe9, 0xc3, 0x22, 0xe5, 0xb2, 0xe8, 0x2d, 0x29, 0xd3, 0x95, 0x43, 0x41, 0xc9, 0xa5, 0x10, 0xf5, + 0x62, 0xac, 0x13, 0x2a, 0x9c, 0x42, 0x27, 0x24, 0xa9, 0xb4, 0x4a, 0x9f, 0x95, 0x4a, 0xeb, 0x5e, + 0xa9, 0x5c, 0x54, 0x4b, 0xf1, 0x90, 0x6b, 0xdf, 0x2a, 0xc0, 0x9c, 0xe9, 0x62, 0xde, 0x7d, 0x72, + 0x03, 0xe6, 0x9a, 0x7e, 0xe8, 0x06, 0x8d, 0xaa, 0xec, 0x97, 0x3c, 0xa0, 0x20, 0xfb, 0xa8, 0x67, + 0x8a, 0x42, 0x3a, 0xe1, 0xdb, 0x23, 0xbf, 0x37, 0xee, 0x86, 0xf2, 0x84, 0x1f, 0x32, 0x90, 0x29, + 0xca, 0xc8, 0xe7, 0x60, 0x9e, 0x73, 0x8e, 0x0c, 0xc5, 0xe8, 0x6e, 0x3d, 0x62, 0x40, 0xcc, 0x57, + 0x13, 0x21, 0xa0, 0x4c, 0xcb, 0x04, 0x8c, 0x92, 0x24, 0xd3, 0x66, 0x64, 0x06, 0x21, 0xaa, 0xcf, + 0x4c, 0x11, 0xd5, 0xdf, 0x80, 0x59, 0x3d, 0x08, 0xdc, 0x50, 0xc4, 0x6a, 0x58, 0x8c, 0xa2, 0xe5, + 0x05, 0x6e, 0xc8, 0x18, 0x3b, 0x58, 0x6e, 0x72, 0x3c, 0xed, 0x2f, 0x0b, 0x30, 0x83, 0x7f, 0xa2, + 0x19, 0x76, 0xd4, 0x3d, 0x4c, 0x98, 0x61, 0x47, 0xdd, 0x43, 0x13, 0xa1, 0xe4, 0x36, 0x6a, 0x2a, + 0x44, 0x52, 0x36, 0xde, 0x7a, 0x54, 0xc1, 0xf7, 0x62, 0xb0, 0x29, 0xe3, 0x44, 0x5e, 0x03, 0xc5, + 0xdc, 0x08, 0x2d, 0xe7, 0xa1, 0xd0, 0xb2, 0x78, 0x8b, 0x31, 0xc8, 0x97, 0x1f, 0x98, 0x85, 0x96, + 0x85, 0xbd, 0xb1, 0xab, 0xdf, 0x79, 0xeb, 0x6d, 0xde, 0x50, 0xd6, 0x1b, 0x87, 0xce, 0x9d, 0xb7, + 0xde, 0x36, 0x79, 0x09, 0xed, 0x5f, 0xac, 0x33, 0x1a, 0x73, 0x59, 0x20, 0x01, 0xec, 0x5f, 0x6c, + 0x1b, 0x1a, 0x6e, 0xcd, 0x18, 0x81, 0xdc, 0x81, 0x05, 0x1e, 0xd1, 0x02, 0xf1, 0xa5, 0x88, 0x13, + 0x3c, 0xe2, 0x05, 0xa3, 0x90, 0x91, 0x98, 0x59, 0x8f, 0x0f, 0x90, 0x48, 0x1d, 0xcd, 0xcd, 0x7a, + 0x62, 0x08, 0x03, 0x53, 0x42, 0xa1, 0x55, 0x62, 0x76, 0xc1, 0x38, 0x40, 0x00, 0x56, 0x89, 0x1b, + 0x0f, 0x31, 0xe3, 0x47, 0x84, 0xa0, 0xfd, 0x61, 0x01, 0xca, 0xed, 0xfe, 0xf8, 0xc0, 0x1b, 0x3c, + 0xb8, 0x4d, 0x08, 0xe0, 0x35, 0x4e, 0xa4, 0x84, 0xa1, 0x7f, 0x93, 0x8b, 0x50, 0x16, 0x37, 0x37, + 0xb1, 0x21, 0x05, 0xfc, 0xd6, 0xb6, 0x0e, 0x62, 0xdc, 0x79, 0x34, 0x37, 0xf1, 0x93, 0xdc, 0x86, + 0xe8, 0xfe, 0x35, 0xe9, 0xa2, 0x56, 0xa2, 0x8b, 0xc5, 0x8c, 0xd0, 0xc8, 0x6b, 0x80, 0x87, 0x04, + 0xbf, 0x3c, 0x08, 0x85, 0x36, 0xab, 0x1a, 0x97, 0x53, 0x18, 0x09, 0xa2, 0x91, 0x37, 0x81, 0x4f, + 0x4c, 0xec, 0xf5, 0xf8, 0xf4, 0xe2, 0x04, 0x2c, 0xe9, 0xab, 0x20, 0xe1, 0xa8, 0xe4, 0x4b, 0xb0, + 0xd0, 0x1d, 0xb9, 0x68, 0xc9, 0x74, 0xfa, 0xe2, 0xc5, 0xea, 0x46, 0x82, 0xb2, 0x12, 0x97, 0x3f, + 0xb8, 0x6d, 0xca, 0xe8, 0xda, 0xf7, 0xe7, 0x61, 0x51, 0xae, 0x0f, 0x31, 0xe1, 0x6c, 0xd0, 0xa7, + 0x77, 0x77, 0xee, 0x49, 0x37, 0xc4, 0x42, 0x7e, 0x9c, 0x5e, 0x4b, 0x56, 0x88, 0xe2, 0x31, 0xb7, + 0x3a, 0x11, 0x8a, 0x63, 0xf7, 0x8c, 0xb9, 0x1a, 0xc4, 0x60, 0x86, 0x47, 0x74, 0x28, 0xfb, 0xc3, + 0xe0, 0xc0, 0x1d, 0x78, 0xc2, 0xde, 0xf2, 0x62, 0x82, 0x51, 0x8b, 0x17, 0x66, 0x78, 0x45, 0x64, + 0xe4, 0x2d, 0x98, 0xf5, 0x87, 0xee, 0xc0, 0xf1, 0xf8, 0x19, 0x77, 0x29, 0xc5, 0xc0, 0x1d, 0xe8, + 0x35, 0x89, 0x90, 0x23, 0x93, 0xd7, 0xa1, 0xe4, 0x3f, 0x89, 0xc6, 0xeb, 0x62, 0x92, 0xe8, 0x49, + 0xe8, 0x48, 0x24, 0x88, 0x48, 0x09, 0x3e, 0x74, 0x8e, 0xf6, 0xf9, 0x88, 0x25, 0x09, 0xee, 0x39, + 0x47, 0xfb, 0x32, 0x01, 0x45, 0x24, 0xef, 0x03, 0x0c, 0x9d, 0x03, 0x77, 0x64, 0xf7, 0xc6, 0xe1, + 0x31, 0x1f, 0xb7, 0x2b, 0x09, 0xb2, 0x36, 0x2d, 0xae, 0x8e, 0xc3, 0x63, 0x89, 0x76, 0x7e, 0x28, + 0x80, 0x44, 0x07, 0x38, 0x72, 0xc2, 0xd0, 0x1d, 0x1d, 0xf9, 0xdc, 0x95, 0x31, 0x8e, 0xfd, 0xc8, + 0x18, 0x34, 0xa2, 0x62, 0x89, 0x83, 0x44, 0x84, 0x95, 0xf6, 0x46, 0x0e, 0x5a, 0xd5, 0x33, 0x95, + 0xf6, 0x46, 0x89, 0x56, 0x52, 0x44, 0xf2, 0x79, 0x98, 0xeb, 0x79, 0x41, 0xd7, 0x1f, 0xf5, 0x78, + 0x8c, 0x96, 0xcb, 0x09, 0x9a, 0x2a, 0x2b, 0x93, 0xc8, 0x04, 0x3a, 0xad, 0x2d, 0x8f, 0xfd, 0xda, + 0xf4, 0x9f, 0xa2, 0x9a, 0x3f, 0x5d, 0x5b, 0x2b, 0x2a, 0x96, 0x6b, 0x1b, 0x13, 0xd1, 0xa1, 0x3c, + 0xf0, 0xc2, 0xbe, 0xf3, 0x98, 0xdb, 0xce, 0x93, 0x43, 0xb9, 0x83, 0x45, 0xf2, 0x50, 0x32, 0x64, + 0x72, 0x17, 0xca, 0x22, 0x1d, 0x04, 0x7f, 0x07, 0x9a, 0xac, 0x34, 0x4f, 0xe7, 0x20, 0x57, 0x9a, + 0x27, 0x80, 0xa0, 0xfd, 0x13, 0x74, 0xbd, 0x23, 0xfe, 0x7c, 0x33, 0xd9, 0x3f, 0x56, 0xa5, 0xd6, + 0x90, 0xfb, 0x87, 0x22, 0x92, 0xf7, 0x60, 0x8e, 0xae, 0xdf, 0x9e, 0x7f, 0xc0, 0xa3, 0x5c, 0x68, + 0xc9, 0xfe, 0x61, 0x65, 0x99, 0xe9, 0x2a, 0x88, 0xe8, 0x42, 0x76, 0x9e, 0x06, 0xb6, 0xd7, 0xc5, + 0x90, 0xa0, 0xe9, 0xe5, 0xa8, 0x3f, 0xb4, 0x6a, 0x15, 0x89, 0x6c, 0xc6, 0x79, 0x1a, 0xd4, 0xba, + 0xe4, 0x0e, 0xcc, 0x60, 0xb6, 0x14, 0x1e, 0xff, 0x33, 0x49, 0x83, 0x79, 0x52, 0x64, 0x1a, 0x44, + 0xa5, 0x03, 0x79, 0x14, 0xe0, 0x8b, 0x18, 0x9e, 0xb3, 0x24, 0xd9, 0x27, 0x0d, 0x0b, 0x9f, 0xc9, + 0xc8, 0x55, 0xe4, 0xe8, 0xb4, 0x8a, 0x03, 0x37, 0xb4, 0xbd, 0x8f, 0x78, 0xd6, 0x91, 0xe4, 0xe7, + 0x9a, 0x6e, 0x58, 0xfb, 0x8a, 0xfc, 0xb9, 0x81, 0x1b, 0xd6, 0x3e, 0xe2, 0x43, 0x77, 0x38, 0x7e, + 0x8c, 0xba, 0xf4, 0x9c, 0xa1, 0x3b, 0x1c, 0xa7, 0x87, 0xee, 0x70, 0xfc, 0x98, 0x92, 0x79, 0x83, + 0x70, 0x3c, 0x70, 0xf9, 0x7b, 0xcc, 0x24, 0x59, 0x0d, 0x8b, 0x64, 0x32, 0x86, 0x4c, 0xae, 0x00, + 0xc4, 0xce, 0x0b, 0xcc, 0x2c, 0x64, 0x4a, 0x90, 0x2f, 0x94, 0xfe, 0xfb, 0x3f, 0xbd, 0xaa, 0x6c, + 0x01, 0x94, 0x45, 0xa8, 0x20, 0x2a, 0x86, 0xaf, 0xe5, 0xd5, 0x85, 0x5c, 0x87, 0x45, 0x39, 0x90, + 0x11, 0x3f, 0x0c, 0x16, 0x9c, 0xa1, 0x27, 0x42, 0x19, 0x4d, 0xcf, 0x47, 0xf1, 0x2a, 0xac, 0x26, + 0x9e, 0x2d, 0xc5, 0x7e, 0x84, 0xa6, 0x2a, 0x17, 0xe0, 0xd9, 0x5b, 0x01, 0x08, 0x42, 0x67, 0x14, + 0xda, 0x3d, 0x27, 0x3c, 0x8d, 0x56, 0xb8, 0x4c, 0xf7, 0x73, 0xe6, 0x25, 0x8e, 0x74, 0x55, 0x27, + 0x74, 0x59, 0xe3, 0xb4, 0x3a, 0x5c, 0x9c, 0xb8, 0xd7, 0x92, 0x57, 0x40, 0xdd, 0x77, 0xb8, 0xa6, + 0xb5, 0x7b, 0xe8, 0x0c, 0x06, 0x6e, 0x9f, 0x37, 0x6c, 0x45, 0xc0, 0x2b, 0x0c, 0xcc, 0xb9, 0xbd, + 0x2f, 0xf5, 0x8e, 0xb4, 0xc8, 0x4e, 0xd1, 0x3b, 0x9c, 0xc1, 0xf7, 0x14, 0xb8, 0x3c, 0x6d, 0xcb, + 0x26, 0x1b, 0x50, 0x1e, 0x8e, 0x3c, 0x1f, 0xaf, 0x06, 0xbc, 0x0f, 0xc5, 0x6f, 0x4c, 0xd7, 0x81, + 0x32, 0x6c, 0xe8, 0x1c, 0xf0, 0x77, 0x40, 0xe6, 0x3c, 0x42, 0x3a, 0xce, 0x41, 0x40, 0xbb, 0xb8, + 0xe7, 0xee, 0x3b, 0xe3, 0x7e, 0x68, 0x07, 0xdd, 0x43, 0xb7, 0x87, 0x2f, 0xf5, 0xd0, 0x01, 0xd3, + 0x54, 0x79, 0x81, 0x25, 0xe0, 0x99, 0x1a, 0xcf, 0x4c, 0xa8, 0xf1, 0xbd, 0x52, 0x59, 0x51, 0x0b, + 0x26, 0x7a, 0xbc, 0x69, 0xdf, 0x2c, 0xc0, 0xfa, 0xa4, 0x3d, 0x8a, 0xbc, 0x9b, 0xd7, 0x07, 0xcc, + 0x58, 0x24, 0xc3, 0x65, 0x63, 0x91, 0x3c, 0x7b, 0xee, 0x40, 0xf4, 0xce, 0xee, 0xa4, 0x98, 0x19, + 0x02, 0x46, 0x69, 0x86, 0x4e, 0x10, 0x3c, 0xa5, 0xdb, 0x70, 0x51, 0x8a, 0xdd, 0xcc, 0x61, 0x32, + 0x8d, 0x80, 0x91, 0x77, 0x00, 0xba, 0x7d, 0x3f, 0x70, 0xd1, 0x27, 0x83, 0xcb, 0x77, 0xec, 0xf5, + 0x40, 0x04, 0x95, 0x8d, 0xf0, 0x08, 0xad, 0xf8, 0x3d, 0x31, 0x9f, 0x1c, 0xb8, 0x30, 0xe1, 0x50, + 0xa2, 0xc3, 0x83, 0x0f, 0xe7, 0xd8, 0x1e, 0xc4, 0x53, 0xdd, 0x51, 0x08, 0x4b, 0xd1, 0x94, 0xee, + 0xf1, 0xc2, 0xa4, 0x39, 0x72, 0x0c, 0x24, 0x7b, 0xf2, 0x50, 0xee, 0xdc, 0x5b, 0x7e, 0x3c, 0x8a, + 0xb8, 0x33, 0xc8, 0xde, 0xa8, 0x4f, 0xae, 0xc2, 0x82, 0x48, 0xca, 0x4b, 0xef, 0x4f, 0x8c, 0x39, + 0x70, 0xd0, 0x7d, 0x17, 0x27, 0x0f, 0x06, 0xbe, 0x65, 0xa9, 0x77, 0xd8, 0xca, 0x9b, 0x47, 0x48, + 0xe7, 0x78, 0x28, 0x5a, 0x77, 0x59, 0xcc, 0xef, 0xa4, 0x3c, 0xc0, 0x4b, 0xff, 0xa1, 0x22, 0x86, + 0x3f, 0x7b, 0xa0, 0x9e, 0x54, 0x3f, 0x02, 0xf8, 0x98, 0x8d, 0x57, 0x0c, 0xff, 0xa6, 0x92, 0xa2, + 0x58, 0x75, 0x5c, 0x52, 0xe4, 0x3f, 0xc9, 0x0d, 0x58, 0x19, 0x31, 0x7f, 0xe4, 0xd0, 0xe7, 0xfd, + 0xc9, 0xb2, 0xd3, 0x2c, 0x31, 0x70, 0xc7, 0xc7, 0x3e, 0xe5, 0xf5, 0xba, 0x17, 0x75, 0x98, 0x24, + 0x5f, 0x90, 0x5b, 0x30, 0x4f, 0xe5, 0x0b, 0x0c, 0x99, 0x94, 0x7a, 0x45, 0x83, 0x78, 0x28, 0xad, + 0x99, 0xe5, 0x0f, 0xf9, 0xdf, 0x9c, 0xd7, 0xaf, 0x45, 0x1b, 0x60, 0x72, 0x57, 0x25, 0xe7, 0x61, + 0x96, 0x25, 0x93, 0xe6, 0x6d, 0xe3, 0xbf, 0xc8, 0xcb, 0xb0, 0xcc, 0x9e, 0xbe, 0xa6, 0x06, 0x76, + 0x09, 0xa1, 0xd1, 0xf4, 0x3e, 0x5d, 0x6a, 0x23, 0x5e, 0x89, 0x7f, 0x53, 0x10, 0x2d, 0x92, 0x45, + 0x2c, 0x72, 0x01, 0xe6, 0xfc, 0xd1, 0x81, 0xd4, 0xbf, 0xb3, 0xfe, 0xe8, 0x80, 0x76, 0xee, 0x4d, + 0x50, 0xd9, 0xcb, 0x32, 0x16, 0xe1, 0x23, 0x38, 0x1e, 0x30, 0x1d, 0x4c, 0xd9, 0x5c, 0x66, 0xf0, + 0xbd, 0xc0, 0x1d, 0x59, 0xc7, 0x83, 0x2e, 0xc5, 0x0c, 0x02, 0xdf, 0x96, 0xc3, 0xaf, 0xf1, 0x8a, + 0x2c, 0x07, 0x81, 0x1f, 0xc7, 0x61, 0xeb, 0x91, 0x2d, 0x58, 0xa2, 0x7c, 0xa2, 0x28, 0x72, 0x7c, + 0x1b, 0x7e, 0x21, 0x2b, 0x01, 0x1e, 0x0f, 0xba, 0xa2, 0x8a, 0xe6, 0x62, 0x20, 0xfd, 0x22, 0xf7, + 0x41, 0x95, 0x44, 0x65, 0x7c, 0x6a, 0x9c, 0x72, 0xd0, 0x8f, 0xd9, 0x48, 0x22, 0x76, 0x6d, 0xb0, + 0xef, 0x9b, 0x2b, 0xdd, 0x24, 0x20, 0xda, 0x8e, 0x66, 0xd5, 0x39, 0x73, 0x9d, 0x37, 0x37, 0x40, + 0xcf, 0x4f, 0xbb, 0xef, 0x1f, 0xd8, 0xee, 0x27, 0x74, 0x62, 0x68, 0xbf, 0xaf, 0x88, 0x0d, 0x3f, + 0x87, 0x29, 0xd1, 0x60, 0xe9, 0xd0, 0x09, 0xec, 0x20, 0x38, 0x62, 0x0e, 0x89, 0x3c, 0x88, 0xf5, + 0xc2, 0xa1, 0x13, 0x58, 0xc1, 0x91, 0x48, 0xb9, 0x73, 0x8e, 0xe2, 0xf8, 0xce, 0x38, 0x3c, 0xb4, + 0xe5, 0x8b, 0x01, 0xeb, 0xd1, 0xb3, 0x87, 0x4e, 0xd0, 0xa2, 0x65, 0x12, 0x6f, 0xf2, 0x12, 0x2c, + 0x23, 0xdf, 0xae, 0x27, 0x18, 0x63, 0x14, 0x17, 0x73, 0x91, 0x32, 0xee, 0x7a, 0x8c, 0x33, 0x1f, + 0xdc, 0xef, 0x97, 0xe0, 0x7c, 0x7e, 0xef, 0xe1, 0x1a, 0xa2, 0x7d, 0x8e, 0xef, 0x4d, 0x79, 0xdd, + 0xe6, 0x29, 0x84, 0x45, 0xe0, 0xc9, 0x1b, 0xbc, 0x42, 0xee, 0xe0, 0x6d, 0xc2, 0x2a, 0x32, 0xe2, + 0x57, 0x90, 0xbe, 0x17, 0x84, 0x3c, 0xb0, 0x8c, 0xb9, 0x42, 0x0b, 0xd8, 0xa1, 0x53, 0xa7, 0x60, + 0x3a, 0x33, 0xc5, 0xb1, 0xe1, 0x3f, 0x1d, 0xd0, 0x0f, 0xb3, 0x33, 0x63, 0x89, 0x43, 0x5b, 0x08, + 0x24, 0xe7, 0x60, 0xd6, 0x19, 0x0e, 0xe9, 0x27, 0xd9, 0x51, 0x31, 0xe3, 0x0c, 0x87, 0x2c, 0xcf, + 0x14, 0xcb, 0xe8, 0xb5, 0x8f, 0xee, 0x63, 0xdc, 0xff, 0xd5, 0x5c, 0x44, 0x20, 0x73, 0x29, 0x0b, + 0xe8, 0xe6, 0x44, 0x69, 0x05, 0xca, 0x1c, 0xa2, 0x80, 0x33, 0x8c, 0x10, 0x2e, 0x42, 0x59, 0x38, + 0x32, 0xb0, 0xe7, 0x44, 0xe6, 0x9c, 0xc3, 0x9d, 0x18, 0xde, 0x82, 0x0b, 0x3c, 0x7d, 0x98, 0xcd, + 0x9a, 0x34, 0x1c, 0xf2, 0xf7, 0xbc, 0x2c, 0x80, 0xb4, 0xb9, 0xc6, 0x8b, 0x69, 0x4f, 0xea, 0xc3, + 0x61, 0xf4, 0xaa, 0x77, 0x43, 0x90, 0x3d, 0xf6, 0x58, 0xa0, 0x3b, 0xe6, 0xcc, 0x8b, 0x8b, 0x03, + 0x90, 0x72, 0x9d, 0x63, 0x6c, 0xc9, 0x08, 0x62, 0x99, 0x44, 0x2b, 0xc9, 0x66, 0x8a, 0x4f, 0x2e, + 0x3e, 0xa1, 0xb9, 0x1b, 0x07, 0x0d, 0xa1, 0xe4, 0x1d, 0x98, 0x38, 0x17, 0x51, 0x3a, 0x2f, 0x9b, + 0xe7, 0x58, 0x39, 0x73, 0x52, 0xae, 0xfb, 0x07, 0x06, 0x16, 0x92, 0xf7, 0xe1, 0xb2, 0xa8, 0xa0, + 0x13, 0x04, 0xde, 0xc1, 0xc0, 0x16, 0xa3, 0x80, 0x7e, 0x24, 0x28, 0xa1, 0x97, 0xcd, 0x8b, 0x1c, + 0x47, 0x47, 0x94, 0x2a, 0xc3, 0xc0, 0xf7, 0xa0, 0x7c, 0x36, 0x7d, 0x1e, 0x56, 0xf8, 0x65, 0x83, + 0x4b, 0x2a, 0xd8, 0xdb, 0x7c, 0x1f, 0xb5, 0xbd, 0x9e, 0xc8, 0x5d, 0x06, 0x1c, 0x54, 0xeb, 0x09, + 0xca, 0xff, 0xaa, 0xc0, 0xb9, 0xdc, 0xdb, 0x0a, 0xf9, 0x65, 0x60, 0x0f, 0x34, 0x43, 0xdf, 0x1e, + 0xb9, 0x5d, 0x6f, 0xe8, 0x61, 0xc4, 0x1b, 0xa6, 0xcd, 0xbf, 0x33, 0xed, 0x9e, 0x83, 0x8f, 0x3d, + 0x3b, 0xbe, 0x19, 0x11, 0x31, 0x35, 0xa3, 0x3a, 0x4a, 0x81, 0x37, 0x3e, 0x80, 0x73, 0xb9, 0xa8, + 0x39, 0xea, 0xbf, 0xcf, 0xc9, 0xea, 0xbf, 0xd8, 0x3e, 0x9b, 0x6a, 0xb4, 0xa4, 0x16, 0xe4, 0xcd, + 0xfb, 0xa3, 0xa8, 0x79, 0xa9, 0x7b, 0x0d, 0x31, 0xd2, 0x3b, 0x5b, 0xde, 0xd5, 0x5c, 0x10, 0x4d, + 0xde, 0xdc, 0x3e, 0x80, 0x73, 0x7c, 0x79, 0xb1, 0x8d, 0x3d, 0x62, 0xc7, 0x2a, 0xfa, 0x0b, 0x79, + 0xec, 0xd8, 0xba, 0xdb, 0xa1, 0xf8, 0x11, 0xd7, 0xb3, 0x4e, 0x16, 0xc8, 0xdb, 0xf0, 0xab, 0x05, + 0xb1, 0x99, 0xe5, 0x54, 0x27, 0x67, 0xe1, 0x2a, 0x79, 0x0b, 0xf7, 0xf4, 0xbb, 0x46, 0x13, 0x88, + 0xbc, 0x5d, 0xf3, 0x79, 0xcf, 0x7c, 0x09, 0xaf, 0x26, 0x33, 0x05, 0x4a, 0x9b, 0x1f, 0x5b, 0x08, + 0xe6, 0x6a, 0x37, 0x0d, 0xa2, 0x17, 0x02, 0x76, 0x48, 0xd2, 0x4f, 0xb2, 0xf3, 0xbb, 0xcc, 0x00, + 0xb5, 0x1e, 0xb9, 0x06, 0x8b, 0xec, 0x36, 0x9a, 0xd8, 0x55, 0x00, 0x61, 0x3a, 0xdd, 0x5a, 0x44, + 0x1f, 0x28, 0x70, 0xed, 0xa4, 0x3e, 0x24, 0x0f, 0xe1, 0x3c, 0x7a, 0x34, 0x05, 0x7e, 0x34, 0x0c, + 0x76, 0xd7, 0xe9, 0x1e, 0xba, 0x7c, 0xd6, 0x6a, 0xb9, 0x83, 0x31, 0x1c, 0x5a, 0x56, 0x4b, 0x1a, + 0x87, 0xe1, 0xd0, 0x0a, 0x7c, 0xf1, 0xbb, 0x42, 0xc9, 0x79, 0x1d, 0x7a, 0x70, 0x69, 0x0a, 0xa5, + 0xb4, 0x35, 0x2a, 0xf2, 0xd6, 0x78, 0x13, 0xd4, 0x7d, 0xb7, 0x47, 0xef, 0x5a, 0x6e, 0x0f, 0xab, + 0xf6, 0xf1, 0x1d, 0xec, 0xf8, 0x45, 0x73, 0x39, 0x82, 0x5b, 0x81, 0xff, 0xe0, 0x0e, 0xff, 0xca, + 0x91, 0x38, 0xf4, 0xe5, 0x1b, 0x35, 0xb9, 0x05, 0x67, 0x53, 0xd1, 0x84, 0xe2, 0xf0, 0x14, 0xe6, + 0x2a, 0x2d, 0x4a, 0xc6, 0x9e, 0xbb, 0x0e, 0x8b, 0xf2, 0x46, 0x22, 0xc4, 0xcc, 0x5e, 0xbc, 0x75, + 0xf0, 0xcf, 0x8d, 0x45, 0xa3, 0x72, 0x2f, 0xe3, 0xa7, 0xb9, 0xf0, 0xbd, 0x06, 0x24, 0xba, 0x3e, + 0x45, 0x1b, 0x05, 0xff, 0xe0, 0xaa, 0x28, 0x89, 0x56, 0x38, 0xff, 0xec, 0xbf, 0x9e, 0x85, 0xb3, + 0x39, 0xb7, 0x78, 0xf2, 0x1a, 0xa8, 0xde, 0x20, 0x74, 0x0f, 0x46, 0xd2, 0xfd, 0x90, 0x5d, 0x21, + 0x0a, 0xeb, 0x8a, 0xb9, 0x22, 0x95, 0x71, 0xf5, 0xec, 0xec, 0xc8, 0x3d, 0x88, 0x54, 0xbd, 0x26, + 0xff, 0x45, 0x37, 0x10, 0x67, 0x24, 0x34, 0x8f, 0xf4, 0x4f, 0x52, 0x83, 0x55, 0x4c, 0xe6, 0x12, + 0x78, 0x3e, 0xe6, 0x84, 0x41, 0x79, 0xb0, 0x94, 0xb8, 0xeb, 0x63, 0x4d, 0xda, 0x12, 0x12, 0x15, + 0x08, 0x4d, 0x75, 0x98, 0x82, 0x90, 0x2f, 0xc2, 0x86, 0x74, 0xa2, 0xda, 0xa9, 0xd5, 0x87, 0x8f, + 0x47, 0xcc, 0x0b, 0x4e, 0x74, 0xb6, 0x56, 0x13, 0xeb, 0x70, 0x0b, 0x58, 0xd6, 0x6e, 0xaf, 0x37, + 0xb4, 0x33, 0xd9, 0x7f, 0xb0, 0xb9, 0x2c, 0x15, 0xc5, 0x06, 0xc5, 0xaa, 0xf5, 0x86, 0xa9, 0x44, + 0x40, 0xd8, 0xea, 0x76, 0xee, 0x0a, 0x9d, 0xc3, 0x15, 0xfa, 0x82, 0xdc, 0x98, 0xcc, 0xfa, 0xc4, + 0x5e, 0xcc, 0x59, 0xa3, 0x07, 0xb0, 0x1a, 0x9f, 0x74, 0xe2, 0x80, 0x2e, 0xe3, 0xa2, 0xd9, 0x90, + 0x19, 0x0a, 0x09, 0x92, 0x9d, 0xd8, 0x2c, 0xc2, 0x46, 0x86, 0x50, 0x8e, 0x23, 0x33, 0x4e, 0x10, + 0x04, 0xa4, 0x0e, 0x6b, 0xce, 0xd3, 0x40, 0xe4, 0x02, 0x0e, 0xa2, 0x6f, 0xcd, 0x67, 0xbf, 0x25, + 0x6c, 0x8d, 0x8c, 0xd4, 0x24, 0xce, 0xd3, 0x80, 0xa7, 0x08, 0x0e, 0x04, 0xb7, 0x0f, 0x81, 0x30, + 0xb1, 0x23, 0x51, 0x6f, 0x38, 0x89, 0x17, 0x4f, 0x24, 0x9c, 0xa1, 0x94, 0xa3, 0xe1, 0x61, 0xa9, + 0x5c, 0xf3, 0x4e, 0x52, 0x3f, 0xbc, 0x90, 0x30, 0x6e, 0xa6, 0x7b, 0x9b, 0x19, 0x5e, 0x25, 0x7c, + 0xf9, 0xbe, 0x2b, 0x81, 0xf1, 0x8a, 0x83, 0xd1, 0xb2, 0xb0, 0x1e, 0x47, 0xf4, 0x32, 0xba, 0xc8, + 0xaf, 0x38, 0x14, 0x4c, 0x2b, 0xd0, 0x88, 0xaf, 0x9d, 0xdf, 0x51, 0x40, 0x4d, 0x7f, 0x8a, 0x7c, + 0x09, 0x66, 0x99, 0xd0, 0xc1, 0x4f, 0x30, 0x2d, 0xbf, 0x4e, 0x6c, 0xa4, 0x99, 0xfc, 0xb1, 0x7b, + 0xc6, 0xe4, 0x34, 0xe4, 0x6d, 0x28, 0xf9, 0x5e, 0x4f, 0x18, 0x6b, 0xaf, 0x4d, 0xa3, 0x6d, 0xd5, + 0xaa, 0x15, 0x54, 0xf0, 0x7a, 0x3d, 0x7e, 0x4f, 0xda, 0x2a, 0xc3, 0x2c, 0xeb, 0x58, 0xed, 0x43, + 0xb8, 0x34, 0xe5, 0x83, 0xc4, 0x80, 0x95, 0x94, 0x21, 0xfb, 0x94, 0x36, 0x6e, 0x27, 0xb6, 0x71, + 0x8f, 0x84, 0xec, 0xdc, 0x87, 0x8b, 0x13, 0x2b, 0x48, 0x6a, 0x13, 0x77, 0x10, 0x8c, 0xe7, 0x92, + 0x2e, 0x93, 0x27, 0x6b, 0x6a, 0x77, 0xe1, 0x5f, 0xfb, 0x8d, 0x02, 0x9c, 0xcd, 0x99, 0x44, 0x44, + 0x83, 0x82, 0xd8, 0xeb, 0xb3, 0x6e, 0x92, 0xbb, 0x67, 0xcc, 0x82, 0xd7, 0x23, 0x77, 0x01, 0x30, + 0xe7, 0xf2, 0xc8, 0x3d, 0x70, 0x3f, 0xe1, 0x0a, 0x0d, 0x54, 0x33, 0xc4, 0xd0, 0x04, 0xcd, 0x3c, + 0x9a, 0x9e, 0x28, 0x98, 0xdc, 0x06, 0x70, 0x3f, 0xe9, 0xf6, 0xc7, 0x3d, 0x37, 0xba, 0x9d, 0xe5, + 0x7c, 0x46, 0x31, 0xe7, 0x39, 0x56, 0xad, 0x47, 0x76, 0x81, 0x08, 0x12, 0xe9, 0xab, 0xa5, 0x13, + 0xbe, 0xaa, 0x98, 0x2a, 0xa7, 0x6a, 0x8a, 0x8f, 0xf3, 0xd1, 0x9d, 0x87, 0x39, 0x6f, 0x80, 0x25, + 0xf4, 0x4f, 0x8e, 0xa4, 0xfd, 0x73, 0x85, 0xf7, 0x47, 0x72, 0x33, 0x20, 0x1d, 0xe0, 0x7e, 0x12, + 0x7c, 0xe3, 0xb8, 0x31, 0x79, 0xe3, 0x90, 0xcd, 0xcf, 0x3c, 0xb0, 0x0f, 0x02, 0x64, 0x23, 0x2b, + 0x83, 0x3c, 0x87, 0x61, 0x98, 0x0f, 0xdf, 0x07, 0x70, 0x2e, 0x77, 0x63, 0xa7, 0xb7, 0x0d, 0x74, + 0xb7, 0x8e, 0x2f, 0xd2, 0x73, 0xf4, 0x37, 0xbd, 0x49, 0x5f, 0x87, 0xc5, 0xc7, 0xae, 0x33, 0x72, + 0x47, 0xfc, 0x1a, 0xc7, 0x4f, 0x4f, 0x06, 0x93, 0x6f, 0x71, 0xbd, 0xe4, 0x29, 0xc6, 0x2d, 0x4b, + 0xa4, 0x01, 0x67, 0xd9, 0xee, 0xe2, 0x1d, 0xa1, 0xfa, 0x82, 0x5b, 0xa3, 0x94, 0xc4, 0xdd, 0x19, + 0x49, 0xf0, 0x9e, 0x52, 0x43, 0x2c, 0x46, 0x6d, 0xae, 0x1e, 0xa4, 0x41, 0x54, 0xf8, 0x39, 0x9f, + 0x8f, 0x4d, 0xb6, 0x60, 0x81, 0x31, 0x67, 0x8a, 0x2c, 0xe6, 0x46, 0x70, 0x7d, 0xea, 0x17, 0x2a, + 0xf8, 0x0a, 0x29, 0x88, 0xfe, 0xa6, 0x97, 0x37, 0xf4, 0xd8, 0xb2, 0x8f, 0x64, 0x2f, 0x09, 0x73, + 0x11, 0x81, 0xdc, 0x3b, 0x42, 0xfb, 0x2f, 0x8a, 0x68, 0x6a, 0x42, 0x85, 0x4e, 0x4f, 0xe0, 0xc0, + 0x1d, 0x08, 0x4f, 0x91, 0x79, 0x93, 0xff, 0x7a, 0x46, 0xa9, 0x80, 0xbc, 0x03, 0x8b, 0x94, 0xed, + 0xc1, 0x78, 0xc0, 0x4e, 0xe6, 0x62, 0x22, 0xe0, 0x60, 0x83, 0x15, 0xd1, 0x61, 0xdb, 0x3d, 0x63, + 0x2e, 0x1c, 0xc5, 0x3f, 0xc9, 0x2d, 0x98, 0x0f, 0x8e, 0xc2, 0xa1, 0x7c, 0x9e, 0x0b, 0x73, 0xa2, + 0xd5, 0xe8, 0xb4, 0x39, 0x49, 0x99, 0xe2, 0xc4, 0xfa, 0x9d, 0xad, 0x59, 0x66, 0x50, 0xd4, 0x5e, + 0x85, 0x05, 0x89, 0x37, 0x6d, 0x0c, 0x7b, 0xb3, 0x2b, 0x1a, 0xc3, 0x7e, 0xf1, 0xc1, 0x7e, 0x0c, + 0x65, 0xc1, 0x92, 0x10, 0x28, 0x1d, 0xfa, 0x81, 0x90, 0x87, 0xf0, 0x6f, 0x0a, 0xc3, 0x0b, 0x1f, + 0x6d, 0xe4, 0x8c, 0x89, 0x7f, 0xa3, 0xd8, 0x8d, 0x3a, 0x6c, 0x0c, 0x53, 0x8d, 0x7e, 0xda, 0x91, + 0xa6, 0x85, 0xc2, 0x3b, 0xfd, 0x80, 0x79, 0x6f, 0x0b, 0x9d, 0x4f, 0x74, 0x5f, 0x49, 0xd9, 0x1c, + 0x26, 0x89, 0x97, 0x09, 0xe9, 0xba, 0x90, 0x95, 0xae, 0x59, 0x20, 0x39, 0x4e, 0xc9, 0xbe, 0x0c, + 0x08, 0x43, 0xe9, 0x5a, 0x12, 0xa0, 0x4a, 0x09, 0x01, 0x4a, 0xd2, 0x22, 0xc7, 0xa3, 0xc7, 0x84, + 0x73, 0xa1, 0x45, 0x4e, 0x8b, 0x74, 0xdf, 0x8d, 0x66, 0x48, 0xc2, 0xea, 0x41, 0xee, 0xc0, 0x39, + 0xa6, 0x45, 0x61, 0x19, 0xb7, 0xd2, 0xb2, 0xe4, 0x59, 0x2c, 0x64, 0x09, 0x0e, 0x23, 0x99, 0xf2, + 0x64, 0x2d, 0x29, 0x79, 0x03, 0xd6, 0xa2, 0x7c, 0xdb, 0xc1, 0x13, 0x6f, 0xc8, 0xd2, 0x83, 0x1e, + 0x73, 0xfd, 0x06, 0x11, 0x65, 0xd6, 0x13, 0x6f, 0x88, 0xa9, 0x42, 0x45, 0x0f, 0xff, 0x41, 0x41, + 0xe8, 0xde, 0xb7, 0x7c, 0x3f, 0x0c, 0xc2, 0x91, 0x33, 0x4c, 0xd8, 0x75, 0xc9, 0x11, 0x5c, 0xc4, + 0x2a, 0xdd, 0xc1, 0x14, 0x63, 0xfe, 0x48, 0xd8, 0x2a, 0xa2, 0x05, 0xb6, 0x70, 0xe7, 0xf5, 0xa4, + 0xde, 0x4a, 0xa7, 0xd8, 0xba, 0x8c, 0x4c, 0xd7, 0x95, 0xc4, 0x75, 0xf7, 0x8c, 0x79, 0x81, 0xf1, + 0xcc, 0x60, 0x91, 0xdd, 0x9c, 0xbd, 0x26, 0x6d, 0xd8, 0xdd, 0x8a, 0x37, 0x9e, 0x24, 0x57, 0x79, + 0x4b, 0x22, 0xef, 0xc1, 0xbc, 0xd7, 0x93, 0x13, 0x7d, 0xa7, 0x4d, 0x8a, 0xb5, 0x1e, 0x4b, 0xf0, + 0x11, 0xf3, 0xa0, 0x4b, 0xc3, 0xe3, 0xd0, 0xad, 0xa5, 0x84, 0x84, 0xa3, 0xed, 0x0a, 0x35, 0x6f, + 0x96, 0x8c, 0x2c, 0xc7, 0x67, 0x1f, 0x9e, 0x73, 0xb8, 0x0b, 0xc4, 0x29, 0x46, 0x4c, 0xfe, 0x8b, + 0x77, 0xf9, 0xaf, 0xc0, 0xcd, 0xd3, 0xf6, 0x14, 0xdd, 0x37, 0x26, 0x74, 0xfb, 0x3c, 0x0b, 0x2f, + 0x9e, 0xec, 0xbd, 0xeb, 0x20, 0xa7, 0x45, 0xf0, 0xc4, 0x44, 0x11, 0xb0, 0xbd, 0x91, 0xa7, 0xfd, + 0x45, 0x11, 0x96, 0x93, 0x96, 0x7f, 0xf2, 0x2a, 0x94, 0xa4, 0xed, 0xf2, 0x42, 0x8e, 0x7b, 0x00, + 0x6e, 0x92, 0x88, 0x74, 0xaa, 0xed, 0x91, 0xdc, 0x83, 0x65, 0x7c, 0x8b, 0x80, 0x62, 0x5c, 0xe8, + 0x71, 0xab, 0xd6, 0x69, 0xed, 0x55, 0x8b, 0x94, 0x96, 0x1e, 0x8f, 0xb4, 0x50, 0x32, 0xec, 0x96, + 0x26, 0x1b, 0x76, 0x79, 0x53, 0x26, 0x18, 0x76, 0x67, 0xa6, 0x18, 0x76, 0x63, 0x4a, 0xd9, 0xb0, + 0x8b, 0xe6, 0xfd, 0xb9, 0x49, 0xe6, 0xfd, 0x98, 0x86, 0x99, 0xf7, 0x63, 0xc3, 0x6c, 0x79, 0xa2, + 0x61, 0x36, 0xa6, 0xe1, 0x86, 0xd9, 0xd8, 0x54, 0x3a, 0x3f, 0xd1, 0x54, 0x2a, 0x11, 0x31, 0x53, + 0xe9, 0x4b, 0xbc, 0x63, 0x47, 0xce, 0x53, 0x1b, 0x7b, 0x9c, 0xdf, 0x8f, 0xb0, 0xcb, 0x4c, 0xe7, + 0x29, 0x3a, 0x19, 0x53, 0xf1, 0x84, 0x7b, 0x26, 0x6b, 0xdf, 0x4b, 0x6d, 0x43, 0x62, 0xcc, 0x5f, + 0x86, 0x65, 0x76, 0x1a, 0xf3, 0xb0, 0xf5, 0xec, 0x38, 0x5e, 0x32, 0x97, 0x04, 0x94, 0x69, 0x57, + 0x7f, 0x01, 0x56, 0x22, 0x34, 0xae, 0x60, 0xc4, 0x20, 0x08, 0x66, 0x44, 0xcd, 0x55, 0x8b, 0x32, + 0xbf, 0x11, 0x0f, 0xc9, 0x97, 0xe0, 0xc7, 0xe2, 0xb5, 0xbd, 0x06, 0x24, 0x46, 0x8b, 0xde, 0x69, + 0x94, 0x10, 0x75, 0x35, 0x42, 0x8d, 0x1e, 0x53, 0xfc, 0x8e, 0x92, 0xb2, 0x2d, 0xfe, 0xac, 0xaa, + 0xff, 0x2a, 0x44, 0x5f, 0xb7, 0xb9, 0x7d, 0x48, 0xb4, 0x40, 0x15, 0x05, 0x6d, 0x0e, 0xd7, 0x0e, + 0xd2, 0x4a, 0xb4, 0x9f, 0x51, 0xad, 0xb4, 0x3f, 0x28, 0x25, 0x4c, 0x1e, 0xe2, 0x33, 0x54, 0xca, + 0x09, 0x7c, 0x9b, 0x0f, 0x31, 0xdf, 0x84, 0xaf, 0x4f, 0x98, 0xa6, 0xdc, 0x33, 0xdd, 0xb2, 0x5a, + 0x26, 0x04, 0x81, 0x2f, 0x1c, 0xd5, 0x6d, 0xa6, 0x1c, 0x92, 0x6e, 0x7d, 0x82, 0x1d, 0xdb, 0x71, + 0x37, 0xa7, 0xb3, 0x13, 0x3a, 0x65, 0xba, 0x4a, 0x51, 0x49, 0x14, 0xfd, 0x12, 0x1f, 0xd8, 0x03, + 0x34, 0x53, 0x06, 0x49, 0xe6, 0xc5, 0x1c, 0x35, 0x60, 0x86, 0x39, 0xf6, 0x12, 0x72, 0x46, 0x85, + 0x73, 0x20, 0xb3, 0x35, 0x60, 0x11, 0x0d, 0x0a, 0x82, 0x61, 0x29, 0xc7, 0x91, 0x22, 0xdb, 0xf8, + 0x4a, 0xad, 0x61, 0x2e, 0x50, 0x3a, 0xc1, 0xe6, 0x10, 0x2e, 0xca, 0x66, 0x80, 0x64, 0x25, 0x67, + 0x44, 0xb2, 0x89, 0xa9, 0x3d, 0x10, 0x5b, 0x0b, 0xb0, 0xaa, 0xe7, 0x9d, 0x24, 0x40, 0x7c, 0xa9, + 0x0b, 0x17, 0x33, 0x4a, 0xf0, 0xe8, 0x4b, 0xcc, 0xb1, 0xe7, 0xe6, 0x84, 0x2f, 0xa5, 0xb4, 0xe3, + 0xee, 0xc8, 0x3c, 0x1f, 0x24, 0x41, 0xfc, 0x23, 0xf8, 0x12, 0x64, 0xf2, 0xc0, 0x4f, 0x49, 0x50, + 0x1a, 0x8b, 0x51, 0x05, 0x59, 0x8c, 0x92, 0x4d, 0x0f, 0xc5, 0xa4, 0xe9, 0x61, 0x1b, 0xae, 0xd1, + 0x3d, 0x8f, 0xcf, 0x1c, 0xf7, 0x63, 0x77, 0x74, 0xec, 0x0f, 0x30, 0x6e, 0xe1, 0x30, 0x5a, 0xfa, + 0xcc, 0x56, 0x72, 0x99, 0xe2, 0xe1, 0xbc, 0x30, 0x38, 0x56, 0x03, 0x91, 0x58, 0x3c, 0xce, 0x7f, + 0x56, 0x84, 0x17, 0x4f, 0x31, 0xb9, 0xa6, 0xd4, 0xfd, 0xcb, 0x49, 0x61, 0xbf, 0x90, 0x50, 0xc9, + 0x52, 0xa6, 0xfc, 0x04, 0x3b, 0x1e, 0x74, 0x27, 0x88, 0xfa, 0xbf, 0x0c, 0x2b, 0xec, 0x98, 0x62, + 0x4f, 0x61, 0xf6, 0xc7, 0xfd, 0x53, 0x9c, 0x53, 0x97, 0xc4, 0xbb, 0xfd, 0x14, 0x29, 0x1e, 0x5d, + 0xb8, 0x3b, 0x5b, 0x11, 0x8c, 0x74, 0x60, 0x01, 0xd1, 0xf6, 0x1d, 0xaf, 0x7f, 0xaa, 0x07, 0xe4, + 0x22, 0x2a, 0x80, 0x4c, 0xc6, 0x5e, 0xf0, 0x51, 0xc0, 0x36, 0xfe, 0x26, 0x37, 0x60, 0x65, 0x30, + 0x3e, 0xa2, 0x62, 0x2c, 0x9b, 0xb9, 0xdc, 0xe3, 0x78, 0xc6, 0x5c, 0x1a, 0x8c, 0x8f, 0xf4, 0xe1, + 0x10, 0x27, 0x20, 0xba, 0x26, 0xaf, 0x52, 0x3c, 0xb6, 0xc7, 0x08, 0xcc, 0x59, 0xc4, 0xa4, 0x0c, + 0xd8, 0x2e, 0xc3, 0x71, 0xd7, 0x80, 0x3d, 0x54, 0xe1, 0x89, 0x5e, 0xd9, 0x0f, 0xed, 0x7f, 0x16, + 0x84, 0xa2, 0x79, 0xf2, 0x2a, 0xfd, 0xf9, 0x10, 0xe5, 0x0c, 0xd1, 0x4d, 0x50, 0x69, 0xd7, 0xc7, + 0x5b, 0x60, 0x34, 0x46, 0xcb, 0x83, 0xf1, 0x51, 0xd4, 0x77, 0x72, 0xc7, 0xcf, 0xca, 0x1d, 0xff, + 0x8e, 0x50, 0x44, 0xe7, 0x6e, 0x66, 0x93, 0xbb, 0x9c, 0xca, 0x77, 0x37, 0x4e, 0xb7, 0x65, 0xfd, + 0x7c, 0xdc, 0x72, 0xc6, 0x2d, 0x65, 0x95, 0x9d, 0xc9, 0x58, 0x65, 0x73, 0xd6, 0xde, 0x6c, 0xde, + 0xda, 0xcb, 0xd8, 0x80, 0xe7, 0x72, 0x6c, 0xc0, 0xb9, 0x0b, 0xb4, 0x7c, 0xc2, 0x02, 0x9d, 0x97, + 0xe7, 0xc9, 0x0f, 0x0a, 0x70, 0xfd, 0xc4, 0x73, 0xe3, 0xe7, 0x23, 0x9d, 0x33, 0xd2, 0xf9, 0xfd, + 0xf9, 0x17, 0x05, 0x21, 0x2f, 0x27, 0xaf, 0xc1, 0x1f, 0xc0, 0x59, 0x71, 0x0d, 0x66, 0x72, 0x43, + 0xec, 0x2a, 0xb1, 0x70, 0xe7, 0x95, 0xbc, 0x0b, 0x30, 0xa2, 0xe5, 0x5c, 0x52, 0x57, 0xf9, 0xd5, + 0x37, 0x2e, 0xff, 0x7f, 0xe7, 0xd2, 0x4b, 0x1e, 0xc1, 0x79, 0x4c, 0x43, 0xd5, 0x95, 0x9d, 0x3c, + 0xec, 0x91, 0xbb, 0xcf, 0x7b, 0xfd, 0x7a, 0xe6, 0x72, 0xe8, 0x75, 0xa5, 0xea, 0x98, 0xee, 0xfe, + 0xee, 0x19, 0x73, 0x2d, 0xc8, 0x81, 0x73, 0x55, 0x53, 0xea, 0x56, 0xfd, 0xaf, 0x14, 0xd0, 0x4e, + 0xee, 0x35, 0x54, 0x80, 0xa4, 0xbb, 0x7d, 0xde, 0x5c, 0x70, 0xa4, 0x3e, 0x7c, 0x11, 0x96, 0x46, + 0xee, 0xfe, 0xc8, 0x0d, 0x0e, 0x13, 0x5a, 0xca, 0x45, 0x0e, 0x14, 0xdd, 0x23, 0x22, 0xe2, 0x3f, + 0xd3, 0x85, 0x54, 0x10, 0x45, 0xee, 0x93, 0x97, 0xa7, 0x8d, 0x09, 0x9d, 0x59, 0x72, 0x35, 0xd9, + 0x8f, 0xc8, 0x55, 0xa7, 0xa0, 0x16, 0x4d, 0x1e, 0xc3, 0x7f, 0xdf, 0xeb, 0xbb, 0xda, 0xbf, 0x8d, + 0x64, 0xb7, 0xbc, 0xee, 0x24, 0x1f, 0x48, 0x4f, 0xf4, 0x8a, 0x19, 0xb1, 0x34, 0x8f, 0xe4, 0x34, + 0xea, 0xe4, 0xfa, 0x67, 0xa4, 0x4e, 0xbe, 0x2b, 0xfc, 0xfc, 0xe9, 0xa9, 0xf2, 0xe0, 0x36, 0x79, + 0x05, 0xe6, 0x98, 0x6b, 0xbf, 0xa8, 0xee, 0x4a, 0xa2, 0xba, 0x0f, 0x6e, 0x9b, 0xa2, 0x5c, 0xfb, + 0x4e, 0xe4, 0x94, 0x94, 0x69, 0xc4, 0x83, 0xdb, 0xe4, 0x9d, 0xd3, 0x3d, 0xb9, 0x2b, 0x8b, 0x27, + 0x77, 0xd1, 0x73, 0xbb, 0xcf, 0x27, 0x9e, 0xdb, 0xbd, 0x34, 0xbd, 0xb7, 0xb8, 0xbf, 0x1b, 0x8b, + 0x8b, 0x1e, 0x05, 0xb7, 0xd5, 0xbe, 0x55, 0x84, 0x17, 0xa6, 0x52, 0x90, 0xcb, 0x50, 0xd6, 0xdb, + 0xb5, 0x4e, 0x3c, 0xca, 0x74, 0x15, 0x09, 0x08, 0xd9, 0x81, 0xf9, 0x2d, 0x27, 0xf0, 0xba, 0x74, + 0x4a, 0xe7, 0x7a, 0x3e, 0x64, 0xd8, 0x46, 0xe8, 0xbb, 0x67, 0xcc, 0x98, 0x96, 0xd8, 0xb0, 0x8a, + 0xeb, 0x22, 0x91, 0xb6, 0xb6, 0x98, 0xa3, 0x74, 0xcb, 0x30, 0xcc, 0x90, 0xd1, 0x9d, 0x27, 0x03, + 0x24, 0x8f, 0x81, 0x58, 0xd6, 0x6e, 0xc5, 0x1d, 0x85, 0x5c, 0x0d, 0x15, 0x7a, 0xd1, 0xfb, 0xad, + 0x37, 0x4e, 0xe8, 0xbb, 0x0c, 0xdd, 0xee, 0x19, 0x33, 0x87, 0x1b, 0xb9, 0x0e, 0x72, 0x7e, 0x65, + 0x94, 0x82, 0x16, 0x77, 0xcf, 0x98, 0x30, 0x8c, 0xf2, 0x2c, 0xe7, 0xef, 0x0d, 0xbf, 0x22, 0x44, + 0xcf, 0xc9, 0xbd, 0xf5, 0x0c, 0xc9, 0x29, 0x6e, 0x42, 0xb9, 0x2d, 0xdc, 0x62, 0xa5, 0x07, 0xb3, + 0xc2, 0x05, 0xd6, 0x8c, 0x4a, 0xf9, 0xcc, 0xfe, 0x6d, 0x45, 0xa8, 0xe9, 0x4e, 0xee, 0x5b, 0x29, + 0x09, 0x71, 0x6f, 0x7a, 0x12, 0xe2, 0xde, 0x4f, 0x99, 0x84, 0x98, 0x57, 0xca, 0x87, 0x57, 0x4e, + 0x3d, 0x1a, 0xe4, 0x4b, 0xa0, 0x62, 0x92, 0x56, 0x47, 0x1a, 0x59, 0xb6, 0x28, 0x57, 0xa3, 0xcc, + 0x45, 0xbb, 0x3c, 0x35, 0xb6, 0xb9, 0xd2, 0x4d, 0x52, 0xf3, 0x0f, 0xfe, 0x21, 0xcf, 0x5b, 0x55, + 0xeb, 0xb5, 0x53, 0xa6, 0xf7, 0xe7, 0x7d, 0x75, 0x6d, 0x24, 0xd6, 0xe9, 0x8b, 0x52, 0x62, 0xfd, + 0xec, 0xb7, 0x26, 0x3f, 0xbe, 0x96, 0x16, 0xed, 0x3f, 0x2a, 0xc2, 0xe5, 0x69, 0xe4, 0x44, 0x07, + 0xd5, 0x60, 0x81, 0x19, 0xf9, 0x7b, 0x37, 0x7f, 0x24, 0xe7, 0x51, 0x64, 0x41, 0x1b, 0xed, 0x5e, + 0x54, 0x68, 0x66, 0xd0, 0xe9, 0x38, 0x33, 0x58, 0xf4, 0xa4, 0x18, 0xc7, 0x99, 0x93, 0xd2, 0x71, + 0x16, 0xc5, 0xe4, 0x45, 0x98, 0xd5, 0x2b, 0x56, 0x9c, 0x30, 0x1a, 0xdf, 0xfe, 0x39, 0xdd, 0x00, + 0x5f, 0x95, 0xf1, 0x22, 0xf2, 0x4b, 0xd9, 0x1c, 0xe9, 0x3c, 0x53, 0xf4, 0x25, 0xa9, 0x43, 0x32, + 0x29, 0xe5, 0xb0, 0xbe, 0x71, 0x0a, 0x34, 0x9e, 0x55, 0xc8, 0xcc, 0xe6, 0x5b, 0xd7, 0x60, 0xb6, + 0x3d, 0x72, 0x03, 0x37, 0x94, 0xdf, 0xe5, 0x0d, 0x11, 0x62, 0xf2, 0x12, 0xfe, 0x6a, 0xce, 0x39, + 0x66, 0x41, 0xd2, 0x66, 0xe5, 0x60, 0x98, 0xf8, 0xcc, 0x8e, 0x82, 0x4d, 0x09, 0x85, 0x12, 0xd4, + 0x9d, 0xf1, 0xa0, 0x7b, 0xb8, 0x67, 0xd6, 0xb9, 0x58, 0xcb, 0x08, 0xfa, 0x08, 0xa5, 0x0d, 0x0c, + 0x4c, 0x09, 0x45, 0xfb, 0x75, 0x05, 0xd6, 0xf2, 0xda, 0x41, 0x2e, 0x43, 0x69, 0x90, 0x9b, 0x0e, + 0x7e, 0xc0, 0x62, 0x3b, 0x2d, 0xa0, 0x85, 0x76, 0xdf, 0x1f, 0x1d, 0x39, 0xa1, 0xfc, 0x7a, 0x51, + 0x02, 0x9b, 0x68, 0x51, 0xde, 0xc6, 0xbf, 0xc9, 0x55, 0x71, 0x5a, 0x15, 0x33, 0x09, 0xe4, 0xf1, + 0x3f, 0x4d, 0x07, 0xa8, 0xf5, 0xda, 0xad, 0x21, 0x4b, 0x69, 0xf6, 0x26, 0x94, 0x68, 0xb5, 0x52, + 0xb3, 0x97, 0xce, 0x1f, 0xbd, 0x51, 0xe7, 0x48, 0xac, 0x56, 0x81, 0x73, 0xd4, 0x37, 0x11, 0x59, + 0x7b, 0x08, 0xcb, 0x49, 0x0c, 0x62, 0x24, 0xb3, 0x5a, 0x2c, 0xdc, 0x51, 0x39, 0xa7, 0x2d, 0xdf, + 0x67, 0x2f, 0xe8, 0xb7, 0x2e, 0xfe, 0xf0, 0xd3, 0xab, 0x40, 0x7f, 0x32, 0x9a, 0xbc, 0xac, 0x17, + 0xda, 0x6f, 0x16, 0x60, 0x2d, 0x0e, 0xda, 0x25, 0xd6, 0xd0, 0xdf, 0xd8, 0x08, 0x32, 0x7a, 0x22, + 0xc2, 0x89, 0x10, 0x42, 0xb3, 0x0d, 0x9c, 0x12, 0x58, 0x61, 0x07, 0xd6, 0x27, 0xe1, 0x93, 0x57, + 0x61, 0x1e, 0x63, 0xc7, 0x0e, 0x9d, 0xae, 0x2b, 0x6f, 0xb9, 0x03, 0x01, 0x34, 0xe3, 0x72, 0xed, + 0x07, 0x0a, 0x6c, 0xf0, 0x77, 0xdf, 0x0d, 0xc7, 0x1b, 0xa0, 0x41, 0xb0, 0xeb, 0x7e, 0x36, 0x11, + 0x90, 0x76, 0x12, 0xfb, 0xd8, 0xcb, 0xc9, 0xe7, 0xfd, 0x99, 0xaf, 0x4d, 0x6e, 0x2d, 0x79, 0x05, + 0xe3, 0x21, 0x73, 0xdf, 0xc2, 0x12, 0x8b, 0x38, 0x37, 0xa0, 0x00, 0x39, 0xe2, 0x1c, 0x62, 0x68, + 0x7f, 0x1b, 0xae, 0x4c, 0xff, 0x00, 0xf9, 0x3a, 0x2c, 0x61, 0xb6, 0xe1, 0xbd, 0xe1, 0xc1, 0xc8, + 0xe9, 0xb9, 0x42, 0x49, 0x2c, 0x6c, 0x19, 0x72, 0x19, 0x0b, 0xef, 0xcc, 0x23, 0xa0, 0x1d, 0x60, + 0x1e, 0x63, 0x4e, 0x94, 0x08, 0xae, 0x20, 0x73, 0xd3, 0xbe, 0xa9, 0x00, 0xc9, 0xf2, 0x20, 0x6f, + 0xc3, 0xe2, 0x5e, 0xa7, 0x62, 0x85, 0xce, 0x28, 0xdc, 0xf5, 0xc7, 0x23, 0x1e, 0x5b, 0x99, 0x05, + 0xc4, 0x0a, 0xbb, 0x36, 0x33, 0xfd, 0x1e, 0xfa, 0xe3, 0x91, 0x99, 0xc0, 0xc3, 0x3c, 0xb5, 0xae, + 0xfb, 0xa4, 0xe7, 0x1c, 0x27, 0xf3, 0xd4, 0x72, 0x58, 0x22, 0x4f, 0x2d, 0x87, 0x69, 0xdf, 0x55, + 0xe0, 0x92, 0x78, 0xb9, 0xd3, 0xcb, 0xa9, 0x4b, 0x05, 0xc3, 0x3e, 0x8e, 0x44, 0xae, 0x90, 0x69, + 0x82, 0xfe, 0xaa, 0x88, 0x8c, 0x8a, 0x15, 0x44, 0x89, 0x9f, 0xd1, 0x92, 0x2f, 0x43, 0xc9, 0x0a, + 0xfd, 0xe1, 0x29, 0x42, 0xa3, 0xaa, 0xd1, 0x88, 0x86, 0xfe, 0x10, 0x59, 0x20, 0xa5, 0xe6, 0xc2, + 0x9a, 0x5c, 0x39, 0x51, 0x63, 0xd2, 0x80, 0x39, 0x1e, 0x57, 0x3b, 0xe5, 0x8d, 0x39, 0xa5, 0x4d, + 0x5b, 0x2b, 0x22, 0xfe, 0x2a, 0xcf, 0x6a, 0x61, 0x0a, 0x1e, 0xda, 0xdf, 0x57, 0x60, 0x81, 0x8a, + 0x3a, 0xa8, 0x31, 0x78, 0xde, 0x29, 0x9d, 0x14, 0xa1, 0x85, 0x73, 0x71, 0xc4, 0xfe, 0x54, 0xa7, + 0xf1, 0x5b, 0xb0, 0x92, 0x22, 0x20, 0x1a, 0x46, 0xde, 0xeb, 0x7b, 0x5d, 0x87, 0xa5, 0xbd, 0x64, + 0x8e, 0xb9, 0x09, 0x98, 0xf6, 0x77, 0x15, 0x58, 0x6b, 0x3d, 0x09, 0x1d, 0xe6, 0xa1, 0x61, 0x8e, + 0xfb, 0x62, 0xbd, 0x53, 0xf1, 0x4d, 0x3c, 0x01, 0x63, 0x51, 0xc1, 0x98, 0xf8, 0xc6, 0x61, 0x66, + 0x54, 0x4a, 0x76, 0xa1, 0xcc, 0xcf, 0x97, 0x80, 0xe7, 0x80, 0xb8, 0x22, 0xa9, 0x33, 0x62, 0xc6, + 0x1c, 0x89, 0xb6, 0x04, 0xb7, 0x30, 0x4e, 0x63, 0x46, 0xd4, 0xda, 0x5f, 0x2a, 0x70, 0x61, 0x02, + 0x0d, 0x79, 0x17, 0x66, 0x30, 0x62, 0x09, 0x1f, 0xbd, 0xcb, 0x13, 0x3e, 0x11, 0x76, 0x0f, 0x1f, + 0xdc, 0x66, 0x07, 0xd1, 0x11, 0xfd, 0x61, 0x32, 0x2a, 0xf2, 0x01, 0xcc, 0xeb, 0xbd, 0x1e, 0xbf, + 0xd8, 0x15, 0x12, 0x17, 0xbb, 0x09, 0x5f, 0xbc, 0x15, 0xe1, 0xb3, 0x8b, 0x1d, 0x7b, 0x3b, 0xdf, + 0xeb, 0xd9, 0x3c, 0x1a, 0x4b, 0xcc, 0x6f, 0xe3, 0x4b, 0xb0, 0x9c, 0x44, 0x7e, 0xa6, 0x00, 0x12, + 0xdf, 0x51, 0x40, 0x4d, 0xd6, 0xe1, 0x67, 0x13, 0x39, 0x36, 0x6f, 0x98, 0x4f, 0x98, 0x54, 0xff, + 0xa0, 0x00, 0xe7, 0x72, 0x7b, 0x98, 0xbc, 0x06, 0xb3, 0xfa, 0x70, 0x58, 0xab, 0xf2, 0x59, 0xc5, + 0x25, 0x24, 0xb4, 0x6c, 0x24, 0xee, 0xbd, 0x0c, 0x89, 0xbc, 0x09, 0x65, 0xe6, 0x08, 0x54, 0x15, + 0x1b, 0x0e, 0x86, 0xc2, 0xe4, 0x5e, 0x4a, 0xc9, 0x6c, 0x0c, 0x02, 0x91, 0x6c, 0xc3, 0x32, 0x0f, + 0x22, 0x89, 0x5e, 0x61, 0x51, 0xd6, 0x31, 0x74, 0xa4, 0x13, 0xe6, 0x12, 0xe6, 0x4f, 0x96, 0xd8, + 0x3b, 0x53, 0x54, 0xa4, 0x0e, 0x2a, 0xf2, 0x94, 0x39, 0xb1, 0x94, 0x10, 0x92, 0x23, 0xe6, 0x04, + 0x5e, 0x19, 0xca, 0x68, 0xb8, 0xd8, 0x63, 0x88, 0x23, 0x77, 0x10, 0xfe, 0xec, 0x86, 0x2b, 0xfe, + 0xc6, 0xa9, 0x86, 0xeb, 0x77, 0x4b, 0x6c, 0x31, 0xa7, 0xc9, 0xa8, 0x44, 0x23, 0x25, 0x19, 0x42, + 0x89, 0x86, 0xde, 0xd8, 0x78, 0x98, 0xc4, 0x2a, 0xcc, 0xb1, 0xf0, 0x95, 0x62, 0x65, 0xbc, 0x90, + 0x5b, 0x05, 0x86, 0xf3, 0xe0, 0x36, 0x13, 0x5f, 0x58, 0xe8, 0x94, 0xc0, 0x14, 0xa4, 0xe4, 0x01, + 0x2c, 0x54, 0xfa, 0xae, 0x33, 0x18, 0x0f, 0x3b, 0xa7, 0xf3, 0x3f, 0x58, 0xe7, 0x6d, 0x59, 0xec, + 0x32, 0x32, 0xf4, 0x5b, 0xc0, 0x9d, 0x5c, 0x66, 0x44, 0x3a, 0x51, 0x34, 0x85, 0x12, 0xea, 0x4a, + 0xdf, 0x98, 0xd2, 0x3f, 0x69, 0x20, 0xd2, 0x25, 0x43, 0x85, 0xf0, 0x70, 0x0b, 0x36, 0x2c, 0xd7, + 0x9d, 0x20, 0xec, 0x8c, 0x9c, 0x41, 0x80, 0xa1, 0xf4, 0x4f, 0x11, 0x16, 0xf8, 0x12, 0xaf, 0x30, + 0xd3, 0xa1, 0x86, 0x11, 0x29, 0xd3, 0xa1, 0x26, 0xd9, 0x51, 0x79, 0x69, 0xdb, 0x1b, 0x38, 0x7d, + 0xef, 0x1b, 0x22, 0xe8, 0x0c, 0x93, 0x97, 0xf6, 0x05, 0xd0, 0x8c, 0xcb, 0xb5, 0xaf, 0x65, 0xc6, + 0x8d, 0xd5, 0x72, 0x01, 0xe6, 0x78, 0x48, 0x32, 0x16, 0xa2, 0xab, 0x6d, 0x34, 0xab, 0xb5, 0xe6, + 0x8e, 0xaa, 0x90, 0x65, 0x80, 0xb6, 0xd9, 0xaa, 0x18, 0x96, 0x45, 0x7f, 0x17, 0xe8, 0x6f, 0x1e, + 0xbf, 0x6b, 0x7b, 0xaf, 0xae, 0x16, 0xa5, 0x10, 0x5e, 0x25, 0xed, 0xfb, 0x0a, 0x9c, 0xcf, 0x1f, + 0x4a, 0xd2, 0x01, 0x0c, 0xe2, 0xc6, 0x3d, 0x51, 0xde, 0x9e, 0x3a, 0xee, 0xb9, 0xe0, 0x74, 0x30, + 0xb8, 0x90, 0x05, 0x19, 0x2b, 0x08, 0x03, 0x27, 0x8b, 0x5a, 0xe2, 0xf5, 0xcc, 0x82, 0xd7, 0xd3, + 0x2a, 0xb0, 0x3e, 0x89, 0x47, 0xb2, 0xa9, 0x2b, 0xb0, 0xa0, 0xb7, 0xdb, 0xf5, 0x5a, 0x45, 0xef, + 0xd4, 0x5a, 0x4d, 0x55, 0x21, 0xf3, 0x30, 0xb3, 0x63, 0xb6, 0xf6, 0xda, 0x6a, 0x41, 0xfb, 0x13, + 0x05, 0x96, 0x6a, 0xb1, 0xa7, 0xec, 0xf3, 0x2e, 0xbe, 0x2f, 0x24, 0x16, 0xdf, 0x7a, 0x14, 0xee, + 0x30, 0xfa, 0xc0, 0x14, 0x09, 0x72, 0x2b, 0x8a, 0x49, 0x53, 0x4c, 0x78, 0x94, 0xc8, 0xd4, 0x22, + 0xda, 0x47, 0x94, 0x28, 0x2d, 0x19, 0xb3, 0x46, 0x5a, 0xbd, 0xff, 0xa2, 0x08, 0xab, 0x99, 0xef, + 0x12, 0x0b, 0xe6, 0xf4, 0x87, 0x56, 0xab, 0x56, 0xad, 0xf0, 0xd6, 0x5d, 0x8d, 0xbd, 0x2b, 0x31, + 0xef, 0x6f, 0xa6, 0xa6, 0x2c, 0xcc, 0xd0, 0xd3, 0xc0, 0xf6, 0xbd, 0x5e, 0x37, 0xe1, 0xde, 0x2b, + 0x38, 0xe1, 0x69, 0xf8, 0x8d, 0xf1, 0x08, 0x3d, 0x96, 0x79, 0xcb, 0x23, 0xa7, 0x4d, 0x01, 0xcf, + 0x32, 0x46, 0x1f, 0x5e, 0x87, 0x96, 0x67, 0x59, 0xc7, 0xfc, 0x48, 0x13, 0x66, 0x77, 0xbc, 0x70, + 0x77, 0xfc, 0x98, 0xf7, 0xca, 0x95, 0x38, 0x0b, 0xec, 0xee, 0xf8, 0x71, 0x96, 0x2d, 0x6a, 0x4c, + 0x59, 0x88, 0x81, 0x04, 0x4b, 0xce, 0x85, 0xdc, 0x87, 0x19, 0xfd, 0xa1, 0x65, 0xea, 0x7c, 0x85, + 0x4a, 0xfe, 0xab, 0xa6, 0x3e, 0x81, 0x1b, 0x6d, 0xfd, 0xc8, 0x49, 0x70, 0x63, 0x3c, 0xd2, 0x61, + 0x56, 0x4a, 0xcf, 0x14, 0x66, 0x65, 0x6b, 0x09, 0x16, 0xf8, 0xa5, 0x0e, 0xef, 0x4b, 0x9f, 0xc0, + 0xd9, 0x9c, 0xa1, 0x26, 0x0e, 0x7a, 0xc9, 0xa3, 0xd5, 0x5d, 0x1f, 0x1c, 0x3f, 0x3d, 0x74, 0x47, + 0x6e, 0x76, 0xec, 0x92, 0x75, 0x17, 0xb3, 0x24, 0xb7, 0xf6, 0x66, 0x86, 0x9d, 0xf6, 0x47, 0x0a, + 0xac, 0x4f, 0x9a, 0x00, 0xf4, 0x86, 0x9a, 0x0c, 0xe4, 0x76, 0x3e, 0xca, 0x76, 0x98, 0xf4, 0x6e, + 0x17, 0x68, 0xe4, 0x7d, 0x58, 0x60, 0x1e, 0x90, 0xd6, 0x9b, 0x7b, 0x66, 0x8d, 0xaf, 0xdc, 0x17, + 0x7e, 0xf2, 0xe9, 0xd5, 0x0b, 0xdc, 0x69, 0x32, 0x78, 0xd3, 0x1e, 0x8f, 0xbc, 0x98, 0x74, 0x5d, + 0x31, 0x65, 0x0a, 0x7a, 0xa1, 0x70, 0xc6, 0x3d, 0xcf, 0x15, 0xd7, 0x29, 0x11, 0xec, 0x8a, 0xc3, + 0xe4, 0xe3, 0x5d, 0xc0, 0xb4, 0x6f, 0x2b, 0xb0, 0x31, 0x79, 0xb6, 0x51, 0x91, 0xa1, 0xc3, 0x1c, + 0x49, 0x45, 0xb8, 0x29, 0x14, 0x19, 0x22, 0x6f, 0x53, 0x99, 0xa7, 0x40, 0xa4, 0x44, 0x5c, 0xf1, + 0x27, 0xf4, 0x45, 0x48, 0x14, 0xe9, 0x05, 0x65, 0x22, 0x81, 0xa8, 0x3d, 0x82, 0x0b, 0x13, 0xe6, + 0x26, 0x79, 0x2f, 0x37, 0x87, 0x2a, 0x86, 0x13, 0x90, 0xe3, 0x45, 0x24, 0x92, 0x71, 0x4b, 0x70, + 0xed, 0x3f, 0x33, 0xd7, 0xe9, 0x9c, 0x89, 0x4a, 0xa5, 0x1b, 0xcc, 0xd9, 0xa9, 0x0f, 0xba, 0x87, + 0xfe, 0x28, 0x1e, 0x2c, 0x94, 0x6e, 0x42, 0x5a, 0x62, 0x3b, 0x58, 0x94, 0x1a, 0xb4, 0x14, 0x15, + 0xf1, 0x61, 0xb5, 0x3d, 0xf2, 0xf7, 0x3d, 0xf6, 0xf6, 0x94, 0x5d, 0x4a, 0xf9, 0x9a, 0xbe, 0x29, + 0x4d, 0x37, 0x79, 0xfa, 0x64, 0xf0, 0xa3, 0xdc, 0x58, 0x14, 0xcc, 0x7c, 0x73, 0xba, 0x58, 0x60, + 0x66, 0x79, 0x6b, 0x3f, 0x2c, 0xc0, 0xf5, 0x13, 0x39, 0x9e, 0x36, 0xf5, 0xe8, 0xeb, 0x00, 0x9c, + 0x96, 0xf6, 0x80, 0xa4, 0x72, 0x12, 0x95, 0x71, 0x46, 0x03, 0x53, 0x42, 0x21, 0x4f, 0xe0, 0x05, + 0xf1, 0xab, 0xdb, 0x75, 0x87, 0x61, 0x40, 0xeb, 0xc1, 0xc3, 0x49, 0x47, 0x81, 0xb4, 0xca, 0x5b, + 0x2f, 0xff, 0xe4, 0xd3, 0xab, 0xd7, 0x23, 0x1e, 0x0c, 0x93, 0x3d, 0xf0, 0x10, 0x91, 0xa9, 0x51, + 0xf1, 0x35, 0x9d, 0x17, 0xb9, 0x11, 0xaf, 0xa4, 0x52, 0xac, 0xc2, 0x16, 0x2b, 0x29, 0x5e, 0x3f, + 0xbb, 0x40, 0x38, 0x23, 0x4a, 0xb6, 0x2d, 0xdb, 0xb2, 0xd9, 0xae, 0x29, 0x6a, 0xc2, 0x14, 0x69, + 0xac, 0xdc, 0xcc, 0xa1, 0xd1, 0x7e, 0x87, 0x2d, 0xec, 0xdc, 0xdd, 0x81, 0x3c, 0x85, 0x15, 0x2a, + 0x65, 0x48, 0x9d, 0xcd, 0xf7, 0x95, 0x3b, 0x27, 0x0f, 0x74, 0x2d, 0xe4, 0xf1, 0x56, 0xac, 0xf1, + 0xd1, 0x91, 0x33, 0x3a, 0xde, 0xba, 0x28, 0x72, 0x68, 0xa2, 0x34, 0x23, 0x8f, 0xbd, 0x99, 0xfe, + 0x8a, 0xf6, 0xe3, 0x02, 0xbc, 0xfa, 0x0c, 0xbc, 0x49, 0x1b, 0xe6, 0xf1, 0x3e, 0x8f, 0x92, 0xe0, + 0xc9, 0xfa, 0x80, 0xf3, 0xfc, 0x6c, 0xe4, 0xf1, 0x56, 0x22, 0x39, 0x30, 0x66, 0x42, 0xee, 0xd1, + 0xe9, 0xd4, 0x43, 0x7e, 0x27, 0xeb, 0x06, 0xd6, 0x84, 0x9a, 0xcc, 0x1d, 0xf4, 0x62, 0x6e, 0x82, + 0x81, 0x14, 0x4a, 0xae, 0x38, 0x31, 0x94, 0xdc, 0x5b, 0xb0, 0x68, 0x48, 0x0e, 0xb6, 0x7c, 0xf8, + 0xd1, 0x6a, 0x90, 0xf0, 0xc6, 0x35, 0x13, 0x68, 0xe4, 0x8b, 0xb0, 0xcc, 0xbc, 0x07, 0x78, 0xef, + 0x30, 0xdf, 0xb6, 0x19, 0x9e, 0xef, 0x02, 0x4b, 0x44, 0x57, 0x07, 0x66, 0x0a, 0x95, 0x2e, 0xac, + 0xf3, 0x54, 0x2a, 0xe9, 0xbb, 0x41, 0xa0, 0x8f, 0xc3, 0x43, 0x7a, 0xea, 0xb0, 0x7b, 0x3a, 0x79, + 0x07, 0x66, 0x0f, 0x9f, 0xcd, 0x3a, 0xc7, 0xd0, 0x09, 0x01, 0x94, 0xf4, 0x45, 0xc4, 0x0b, 0xfa, + 0x37, 0xf9, 0x3c, 0xcc, 0xa0, 0x92, 0x99, 0x0b, 0xd4, 0x42, 0x11, 0x92, 0xff, 0x69, 0x54, 0x41, + 0x9b, 0x8c, 0x80, 0xae, 0xd6, 0x38, 0x39, 0x28, 0x3f, 0x8f, 0x85, 0xf2, 0x35, 0xca, 0x0f, 0x6a, + 0xce, 0x1f, 0xed, 0x3b, 0x3c, 0xe3, 0xe6, 0x26, 0xac, 0x8a, 0xbd, 0x77, 0x28, 0x72, 0x47, 0x70, + 0xbf, 0x9b, 0x15, 0x1e, 0x95, 0x67, 0x28, 0xf2, 0x47, 0xbc, 0x04, 0xcb, 0x41, 0x70, 0x68, 0xf3, + 0x58, 0x70, 0x4f, 0x44, 0x5a, 0x2a, 0x73, 0x31, 0x08, 0x0e, 0x59, 0x50, 0xb8, 0xfb, 0xee, 0x31, + 0xc5, 0xc2, 0xb7, 0x0c, 0x31, 0x56, 0x99, 0x61, 0x85, 0xfd, 0x20, 0xc2, 0xe2, 0x61, 0x0c, 0x21, + 0xc6, 0xd2, 0xfe, 0x5b, 0x01, 0xe6, 0x1f, 0xd2, 0xcb, 0x2b, 0xaa, 0x64, 0xa7, 0xab, 0x78, 0xef, + 0xc0, 0x42, 0xdd, 0x77, 0xb8, 0x89, 0x9e, 0x87, 0x5c, 0x60, 0x8f, 0x9f, 0xfa, 0xbe, 0x23, 0xac, + 0xfd, 0x81, 0x29, 0x23, 0x9d, 0x10, 0xc7, 0xef, 0x1e, 0xcc, 0xb2, 0x15, 0xce, 0xad, 0x0d, 0x42, + 0x7d, 0x11, 0xd5, 0xe8, 0x16, 0x2b, 0x96, 0x6c, 0xc8, 0x6c, 0x97, 0x90, 0xef, 0xd2, 0xfc, 0xa1, + 0x93, 0xa4, 0x80, 0x9e, 0x39, 0x9d, 0x02, 0x5a, 0xca, 0x01, 0x30, 0x7b, 0x9a, 0x1c, 0x00, 0x1b, + 0x77, 0x61, 0x41, 0xaa, 0xcf, 0x33, 0x69, 0x33, 0x7e, 0xb5, 0x00, 0x4b, 0xd8, 0xaa, 0x68, 0xd7, + 0xfa, 0x9b, 0xa9, 0x4e, 0xff, 0x42, 0x42, 0x9d, 0xbe, 0x2e, 0x8f, 0x17, 0x77, 0xfa, 0x99, 0xac, + 0x47, 0xbf, 0x07, 0xab, 0x19, 0x44, 0xf2, 0x16, 0xcc, 0xd0, 0xea, 0x0b, 0xf5, 0xa3, 0x9a, 0x9e, + 0x01, 0x71, 0xbe, 0x28, 0xda, 0xf0, 0xc0, 0x64, 0xd8, 0xda, 0xff, 0x50, 0x60, 0x91, 0xe7, 0xa2, + 0x1d, 0xec, 0xfb, 0x27, 0x76, 0xe7, 0x8d, 0x74, 0x77, 0xb2, 0xa8, 0xb4, 0xbc, 0x3b, 0xff, 0x4f, + 0x77, 0xe2, 0xdd, 0x44, 0x27, 0x5e, 0x88, 0xb2, 0x47, 0x88, 0xe6, 0x4c, 0xe9, 0xc3, 0xef, 0x61, + 0x3e, 0xa5, 0x24, 0x22, 0xf9, 0x25, 0x98, 0x6f, 0xba, 0x4f, 0x13, 0x5a, 0xbc, 0x1b, 0x13, 0x98, + 0xde, 0x8a, 0x10, 0xd9, 0x9a, 0x62, 0x0f, 0x10, 0xdd, 0xa7, 0x76, 0xc6, 0x37, 0x23, 0x66, 0xb9, + 0xf1, 0x25, 0x58, 0x4e, 0x92, 0x3d, 0xcb, 0xd4, 0xe7, 0x41, 0xaa, 0x30, 0xd0, 0xf2, 0xaf, 0x17, + 0x01, 0xe2, 0xf8, 0x3e, 0x74, 0x01, 0x26, 0xdc, 0xc1, 0x84, 0x01, 0x14, 0x41, 0xf2, 0x1c, 0x17, + 0x5e, 0x62, 0x37, 0xb8, 0xa1, 0xae, 0x30, 0x39, 0xbb, 0xc7, 0x40, 0xc4, 0x28, 0x63, 0x9e, 0xd4, + 0x7d, 0x87, 0xbd, 0x3d, 0x2a, 0x6e, 0xbd, 0x84, 0xc9, 0x9c, 0x22, 0x68, 0x22, 0xf5, 0x42, 0xb9, + 0x3a, 0xe6, 0x49, 0xe4, 0x30, 0xa2, 0x4b, 0x95, 0x22, 0x64, 0x62, 0x66, 0x95, 0x9e, 0x2d, 0x66, + 0x56, 0x1b, 0xe6, 0xbd, 0xc1, 0xc7, 0xee, 0x20, 0xf4, 0x47, 0xc7, 0x68, 0x9d, 0x8c, 0xcd, 0x1e, + 0xb4, 0x0b, 0x6a, 0xa2, 0x8c, 0x8d, 0x03, 0x4a, 0x9a, 0x11, 0xbe, 0x3c, 0x0c, 0x11, 0x30, 0xf2, + 0xdc, 0x99, 0x51, 0x67, 0x59, 0xa8, 0x9d, 0x7b, 0xa5, 0x72, 0x59, 0x9d, 0xbf, 0x57, 0x2a, 0xcf, + 0xab, 0x60, 0x4a, 0xce, 0x06, 0x91, 0x33, 0x81, 0x64, 0xf9, 0x4f, 0x5a, 0xf5, 0xb5, 0xbf, 0x2a, + 0x00, 0xc9, 0x56, 0x83, 0x7c, 0x01, 0x16, 0xd8, 0x06, 0x6b, 0x8f, 0x82, 0x8f, 0xf8, 0x03, 0x4c, + 0xf6, 0x6a, 0x5a, 0x02, 0xcb, 0xe1, 0xaa, 0x19, 0xd8, 0x0c, 0x3e, 0xea, 0x93, 0xaf, 0xc3, 0x59, + 0xec, 0xde, 0xa1, 0x3b, 0xf2, 0xfc, 0x9e, 0x8d, 0xb9, 0x85, 0x9c, 0x3e, 0x8e, 0x55, 0x71, 0xeb, + 0xb5, 0x9f, 0x7c, 0x7a, 0xf5, 0x85, 0x9c, 0xe2, 0x09, 0xc3, 0x80, 0x11, 0x72, 0xda, 0x88, 0xd9, + 0x66, 0x88, 0xa4, 0x03, 0xaa, 0x4c, 0xbf, 0x3f, 0xee, 0xf7, 0xf9, 0xc8, 0x6e, 0xd2, 0xab, 0x41, + 0xba, 0x6c, 0x02, 0xe3, 0xe5, 0x98, 0xf1, 0xf6, 0xb8, 0xdf, 0x27, 0xef, 0x00, 0xf8, 0x03, 0xfb, + 0xc8, 0x0b, 0x02, 0x66, 0xf3, 0x8e, 0x1e, 0xe5, 0xc6, 0x50, 0x79, 0x30, 0xfc, 0x41, 0x83, 0x01, + 0xc9, 0xdf, 0x02, 0x8c, 0x72, 0x89, 0xe1, 0x5f, 0xb9, 0x34, 0xc3, 0x6e, 0x0b, 0x02, 0x98, 0x0c, + 0x70, 0x76, 0xe0, 0x5a, 0xde, 0x37, 0xc4, 0xdb, 0xe5, 0xaf, 0xc2, 0x2a, 0x97, 0x8c, 0x1e, 0x7a, + 0xe1, 0x21, 0xd7, 0xb8, 0x3c, 0x8f, 0xba, 0x46, 0x52, 0x97, 0xfc, 0x69, 0x09, 0x40, 0x7f, 0x68, + 0x89, 0xc8, 0xea, 0xaf, 0xc0, 0x4c, 0x87, 0xb2, 0xe1, 0xfa, 0x68, 0x14, 0xb8, 0x90, 0xaf, 0x6c, + 0xcd, 0x43, 0x0c, 0xba, 0x1a, 0x4d, 0x7c, 0x66, 0x28, 0x74, 0xd1, 0xb8, 0x1a, 0xd9, 0xcb, 0xc3, + 0x44, 0x66, 0x2b, 0x8e, 0x45, 0xea, 0x00, 0x71, 0xac, 0x73, 0xae, 0xd5, 0x58, 0x8d, 0x83, 0x06, + 0xf3, 0x02, 0x9e, 0xb1, 0x33, 0x7e, 0x4b, 0x2e, 0x4f, 0x9f, 0x18, 0x8d, 0xdc, 0x87, 0x52, 0xc7, + 0x89, 0x42, 0x59, 0x4d, 0x88, 0x00, 0x8f, 0xa9, 0xe8, 0x13, 0x51, 0xe0, 0x97, 0x43, 0xe7, 0x40, + 0xae, 0x1d, 0x32, 0x21, 0x06, 0xcc, 0xb6, 0x9d, 0x91, 0x73, 0x14, 0x4c, 0xca, 0x1c, 0xc2, 0x4a, + 0x45, 0xbe, 0x30, 0x04, 0xca, 0x32, 0x05, 0x2b, 0x26, 0x77, 0xa0, 0x68, 0x59, 0x0d, 0xfe, 0x3c, + 0x62, 0x29, 0xbe, 0x4d, 0x58, 0x56, 0x83, 0x09, 0xbd, 0x41, 0x70, 0x24, 0x91, 0x51, 0x64, 0xf2, + 0x45, 0x58, 0x90, 0x2e, 0x29, 0x3c, 0x62, 0x30, 0xf6, 0x81, 0xf4, 0x90, 0x5d, 0xde, 0x34, 0x24, + 0x6c, 0x52, 0x07, 0xf5, 0xfe, 0xf8, 0xb1, 0xab, 0x0f, 0x87, 0x18, 0x43, 0xe7, 0x63, 0x77, 0xc4, + 0x04, 0xb9, 0x72, 0x9c, 0x6a, 0x0b, 0x5f, 0x8d, 0xf6, 0x44, 0xa9, 0xac, 0x0e, 0x49, 0x53, 0x92, + 0x36, 0xac, 0x5a, 0x6e, 0x38, 0x1e, 0x32, 0x6f, 0xc6, 0x6d, 0x76, 0x9d, 0x66, 0xf1, 0x85, 0x31, + 0x2b, 0x51, 0x40, 0x0b, 0x85, 0x23, 0xe9, 0x7e, 0xe6, 0x4a, 0x9d, 0x25, 0xd6, 0x5c, 0x79, 0xc8, + 0xe5, 0x7b, 0xa0, 0x32, 0xed, 0x1e, 0xf8, 0x7a, 0x4e, 0x0c, 0x7c, 0xbc, 0xcd, 0x4a, 0x31, 0xf0, + 0x13, 0x91, 0xef, 0xbf, 0x5b, 0x92, 0xd2, 0xb0, 0xf0, 0xb1, 0x78, 0x17, 0xe0, 0x9e, 0xef, 0x0d, + 0x1a, 0x6e, 0x78, 0xe8, 0xf7, 0xa4, 0x30, 0x05, 0x0b, 0x98, 0x2c, 0xfe, 0x08, 0xc1, 0x7f, 0xf5, + 0xe9, 0x55, 0x09, 0xc9, 0x94, 0xfe, 0x26, 0x9f, 0x93, 0x53, 0xcd, 0x17, 0xe2, 0x18, 0xcb, 0x71, + 0xaa, 0x79, 0x29, 0xc1, 0x3c, 0xb9, 0x8b, 0x29, 0x7f, 0xbd, 0x61, 0x28, 0x09, 0xaf, 0x22, 0xbf, + 0xaf, 0x37, 0x0c, 0xd3, 0x31, 0x0a, 0x24, 0x64, 0xb2, 0x1b, 0x55, 0x5d, 0x64, 0xe9, 0xe6, 0x99, + 0x85, 0x79, 0xa0, 0x03, 0x2c, 0xb2, 0x45, 0x4a, 0x1f, 0x39, 0xd0, 0x41, 0x8a, 0x0c, 0x2b, 0x61, + 0xed, 0x56, 0xb9, 0xee, 0x62, 0x46, 0xaa, 0x44, 0x70, 0xd8, 0xe3, 0x9a, 0x88, 0x44, 0x25, 0x22, + 0x64, 0xb2, 0x05, 0x2b, 0x4c, 0xea, 0xc7, 0x1c, 0xde, 0x98, 0x5e, 0x76, 0x36, 0xde, 0xdb, 0x58, + 0xb6, 0x6f, 0x7a, 0xef, 0x90, 0x3f, 0x9f, 0x22, 0x20, 0xdb, 0x30, 0x83, 0x7a, 0x28, 0xfe, 0xfe, + 0xf0, 0x92, 0xac, 0x09, 0x4d, 0xaf, 0x23, 0xdc, 0x57, 0x50, 0x07, 0x2a, 0xef, 0x2b, 0x88, 0x4a, + 0x7e, 0x11, 0xc0, 0x18, 0x8c, 0xfc, 0x7e, 0x1f, 0x93, 0x4e, 0x95, 0x13, 0xf1, 0x50, 0x38, 0x1f, + 0xe4, 0x12, 0x23, 0xf1, 0x04, 0x09, 0xf8, 0xdb, 0x4e, 0xa5, 0xa6, 0x92, 0x78, 0x69, 0x35, 0x98, + 0x65, 0x8b, 0x11, 0x13, 0xb8, 0xf1, 0x34, 0xb7, 0x52, 0xfa, 0x2f, 0x96, 0xc0, 0x8d, 0xc3, 0xb3, + 0x09, 0xdc, 0x24, 0x02, 0xed, 0x3e, 0xac, 0xe5, 0x35, 0x2c, 0xa1, 0x39, 0x53, 0x4e, 0xab, 0x39, + 0xfb, 0xfd, 0x22, 0x2c, 0x22, 0x37, 0xb1, 0x0b, 0xeb, 0xb0, 0x64, 0x8d, 0x1f, 0x47, 0xd1, 0xcd, + 0xc5, 0x6e, 0x8c, 0xf5, 0x0b, 0xe4, 0x02, 0xd9, 0xd5, 0x21, 0x41, 0x41, 0x0c, 0x58, 0x16, 0x27, + 0xc1, 0x8e, 0x78, 0xab, 0x17, 0xe5, 0x4e, 0x13, 0x4f, 0x18, 0xb9, 0x07, 0xbf, 0xac, 0x16, 0x4b, + 0x12, 0xc5, 0xe7, 0x41, 0xf1, 0x59, 0xce, 0x83, 0xd2, 0xa9, 0xce, 0x83, 0x0f, 0x60, 0x51, 0x7c, + 0x0d, 0x77, 0xf2, 0x99, 0xe7, 0xdb, 0xc9, 0x13, 0xcc, 0x48, 0x3d, 0xda, 0xd1, 0x67, 0xa7, 0xee, + 0xe8, 0xe8, 0x3f, 0x22, 0x56, 0xd9, 0x10, 0x61, 0xd9, 0x8d, 0x5d, 0xfb, 0xf3, 0x22, 0xc0, 0x4e, + 0xa5, 0xfd, 0x53, 0x9c, 0x92, 0x6f, 0xc1, 0x7c, 0xdd, 0x17, 0xae, 0x03, 0x92, 0xcd, 0xb6, 0x2f, + 0x80, 0xb2, 0xb8, 0x10, 0x61, 0x46, 0xa7, 0x5b, 0xf1, 0xb3, 0x38, 0xdd, 0xee, 0xa2, 0x76, 0xf0, + 0x43, 0xb7, 0x1b, 0xc6, 0x69, 0xfc, 0x71, 0xc9, 0x88, 0x28, 0xa3, 0x49, 0xd3, 0xb1, 0x84, 0x4c, + 0x77, 0x27, 0xee, 0x95, 0x28, 0xa2, 0xf6, 0x70, 0x7d, 0x1c, 0xee, 0x4e, 0x22, 0xf4, 0x91, 0x08, + 0x04, 0x24, 0x6f, 0x0f, 0x29, 0xb2, 0xcf, 0x76, 0x40, 0xc8, 0x57, 0x22, 0xf7, 0xf2, 0xb9, 0x69, + 0x3d, 0xa4, 0x65, 0x7a, 0x68, 0xa2, 0x53, 0xb9, 0xf6, 0x7d, 0x45, 0x4e, 0x5c, 0xf9, 0x53, 0x0c, + 0xf5, 0xe7, 0x01, 0x22, 0xdf, 0x2d, 0x31, 0xd6, 0x51, 0xc0, 0x16, 0x06, 0x95, 0x7b, 0x39, 0xc6, + 0x95, 0x5a, 0x53, 0xfc, 0xac, 0x5a, 0xd3, 0x81, 0x85, 0xd6, 0x93, 0xd0, 0x89, 0x9d, 0xfd, 0xc0, + 0x8a, 0x24, 0x59, 0xdc, 0x99, 0x8a, 0xa8, 0xdc, 0x3d, 0x27, 0xc9, 0xc1, 0x13, 0x44, 0x60, 0x89, + 0x50, 0xfb, 0x6b, 0x05, 0x56, 0xe4, 0x98, 0x6d, 0xc7, 0x83, 0x2e, 0x79, 0x8f, 0xe5, 0xd1, 0x51, + 0x12, 0x57, 0x16, 0x09, 0x89, 0x6e, 0xb9, 0xc7, 0x83, 0x2e, 0x13, 0x80, 0x9c, 0xa7, 0x72, 0x65, + 0x29, 0x21, 0x79, 0x0c, 0x8b, 0x6d, 0xbf, 0xdf, 0xa7, 0x62, 0xcd, 0xe8, 0x63, 0x7e, 0x01, 0xa0, + 0x8c, 0xd2, 0x8a, 0x49, 0x51, 0xa1, 0xad, 0x17, 0xf9, 0x3d, 0xf7, 0xc2, 0x90, 0xee, 0xf7, 0x1e, + 0xa7, 0x8b, 0xd9, 0x7e, 0x07, 0x1f, 0xe3, 0xcb, 0x3c, 0xe3, 0xb3, 0x29, 0x99, 0x80, 0x51, 0xae, + 0x25, 0x2d, 0xc6, 0x7a, 0x4e, 0x39, 0x9b, 0xb4, 0xbf, 0xa3, 0xc0, 0xb5, 0x6c, 0xd3, 0x2a, 0x7d, + 0x7f, 0xdc, 0xeb, 0x8c, 0x1c, 0xaf, 0x5f, 0xf7, 0x0f, 0x02, 0x96, 0x7f, 0xe4, 0x20, 0xb6, 0x73, + 0xf0, 0xfc, 0x23, 0x07, 0x5e, 0x3a, 0xff, 0x08, 0xc6, 0xe8, 0x78, 0x13, 0xca, 0xd6, 0x57, 0xac, + 0xaf, 0x8c, 0x5d, 0x71, 0x17, 0x66, 0xfb, 0x43, 0xf0, 0x51, 0x60, 0x7f, 0x44, 0x81, 0xf2, 0x89, + 0x21, 0x10, 0xb5, 0xff, 0x50, 0x00, 0x92, 0xad, 0x87, 0xbc, 0x05, 0x2b, 0xff, 0x17, 0x44, 0xf2, + 0x94, 0x28, 0x5b, 0x7a, 0x26, 0x51, 0xf6, 0x23, 0x50, 0xbb, 0xb4, 0x1f, 0xed, 0x90, 0x76, 0xa4, + 0xdd, 0xf7, 0xa3, 0x13, 0xe1, 0x17, 0x26, 0xce, 0xa9, 0x64, 0xc7, 0xb3, 0x3d, 0x29, 0xcd, 0x44, + 0x3e, 0xdc, 0xba, 0x09, 0x7c, 0xed, 0xf7, 0x14, 0x58, 0xcb, 0x9b, 0x02, 0xf4, 0xf0, 0x94, 0x4f, + 0xd3, 0xe8, 0x2c, 0xc7, 0xc3, 0x53, 0x3e, 0x80, 0x93, 0x27, 0x7a, 0x8a, 0x28, 0xdd, 0x1f, 0x85, + 0x67, 0xe9, 0x0f, 0xed, 0xc7, 0x45, 0x58, 0x64, 0x86, 0xfd, 0x5d, 0xd7, 0xe9, 0x87, 0x87, 0x74, + 0x70, 0x45, 0x42, 0x61, 0xc9, 0xfd, 0x7b, 0x4a, 0x26, 0xe1, 0x3b, 0x50, 0x6e, 0xd3, 0xc5, 0xd3, + 0xf5, 0xfb, 0xb2, 0x52, 0x70, 0xc8, 0x61, 0xf2, 0xc4, 0x12, 0x78, 0x74, 0xee, 0x26, 0x94, 0xfa, + 0x2c, 0x87, 0x25, 0x42, 0xe4, 0xb9, 0xcb, 0xd5, 0xfb, 0x9f, 0xc0, 0xd9, 0xd8, 0x57, 0x23, 0x32, + 0x1c, 0x9c, 0xe2, 0xa5, 0xdb, 0x26, 0xb7, 0x9a, 0x5c, 0x89, 0xdd, 0x3f, 0xd0, 0xc2, 0x80, 0xa5, + 0xa9, 0xa4, 0x3a, 0x79, 0x9f, 0x20, 0xf7, 0x41, 0x8d, 0xc1, 0x3c, 0xdb, 0x0f, 0x93, 0x78, 0x31, + 0x9a, 0x9d, 0xc4, 0x36, 0x93, 0xf8, 0x27, 0x43, 0x48, 0x0f, 0xb9, 0x18, 0x66, 0xc4, 0x8f, 0x5a, + 0x85, 0x11, 0x31, 0xe2, 0x85, 0x36, 0x0b, 0xf9, 0x90, 0x4b, 0x91, 0xd1, 0x31, 0x12, 0xa6, 0x8e, + 0xb9, 0x78, 0x8c, 0xb8, 0x91, 0x43, 0x1e, 0x23, 0x8e, 0xb5, 0xf9, 0x5b, 0x0a, 0xac, 0xd4, 0xf4, + 0x06, 0x4f, 0x48, 0xcb, 0x7a, 0xf5, 0x3a, 0xbc, 0x50, 0xd3, 0x1b, 0x76, 0xbb, 0x55, 0xaf, 0x55, + 0x1e, 0xd9, 0xb9, 0x79, 0xe6, 0x5e, 0x80, 0x8b, 0x59, 0x94, 0xd8, 0xad, 0xe5, 0x32, 0xac, 0x67, + 0x8b, 0x45, 0x2e, 0xba, 0x7c, 0x62, 0x91, 0xb6, 0xae, 0xb8, 0xf9, 0x3e, 0xac, 0x88, 0xbc, 0x6b, + 0x9d, 0xba, 0x85, 0x99, 0x5d, 0x57, 0x60, 0xe1, 0x81, 0x61, 0xd6, 0xb6, 0x1f, 0xd9, 0xdb, 0x7b, + 0xf5, 0xba, 0x7a, 0x86, 0x2c, 0xc1, 0x3c, 0x07, 0x54, 0x74, 0x55, 0x21, 0x8b, 0x50, 0xae, 0x35, + 0x2d, 0xa3, 0xb2, 0x67, 0x1a, 0x6a, 0x61, 0xf3, 0x9f, 0x28, 0xb0, 0xb4, 0x37, 0xec, 0x39, 0xa1, + 0x3b, 0xe2, 0x2d, 0xba, 0x02, 0x1b, 0x7b, 0xed, 0xaa, 0xde, 0x31, 0xcc, 0xfc, 0xe6, 0x9c, 0x83, + 0xd5, 0x54, 0x79, 0xeb, 0xbe, 0xaa, 0x90, 0x4b, 0x70, 0x21, 0x05, 0xae, 0xd6, 0x2c, 0x7d, 0x8b, + 0xb5, 0xe2, 0x22, 0x9c, 0x4b, 0x15, 0xb6, 0x6b, 0xcd, 0xa6, 0x51, 0x55, 0x8b, 0xb4, 0x81, 0x99, + 0xcf, 0x99, 0x86, 0x5e, 0xa5, 0xa4, 0x6a, 0x69, 0xf3, 0x7d, 0x58, 0x6e, 0x47, 0x6f, 0x78, 0xd0, + 0x6b, 0x66, 0x0e, 0x8a, 0xa6, 0xfe, 0x50, 0x3d, 0x43, 0x00, 0x66, 0xdb, 0xf7, 0x2b, 0xd6, 0xed, + 0xdb, 0xaa, 0x42, 0x16, 0x60, 0x6e, 0xa7, 0xd2, 0xb6, 0xef, 0x37, 0x2c, 0xb5, 0x40, 0x7f, 0xe8, + 0x0f, 0x2d, 0xfc, 0x51, 0xdc, 0x7c, 0x03, 0x6d, 0xc5, 0x9f, 0x1c, 0xd7, 0xbd, 0x20, 0x74, 0x07, + 0xee, 0x08, 0xfb, 0x68, 0x11, 0xca, 0x96, 0x4b, 0xe5, 0x95, 0xd0, 0x65, 0x1d, 0xd4, 0x18, 0xf7, + 0x43, 0x6f, 0xd8, 0x77, 0x3f, 0x51, 0x95, 0xcd, 0xbb, 0xb0, 0x62, 0xfa, 0xe3, 0xd0, 0x1b, 0x1c, + 0x58, 0x21, 0xc5, 0x38, 0x38, 0xc6, 0x36, 0x37, 0xf5, 0xc6, 0x56, 0x6d, 0x67, 0xaf, 0xb5, 0x67, + 0xd9, 0x0d, 0xbd, 0x53, 0xd9, 0x65, 0x3e, 0x3b, 0x8d, 0x96, 0xd5, 0xb1, 0x4d, 0xa3, 0x62, 0x34, + 0x3b, 0xaa, 0xb2, 0xf9, 0x9b, 0xa8, 0xc1, 0xed, 0xfa, 0x83, 0xde, 0xb6, 0xd3, 0x0d, 0xfd, 0x11, + 0x56, 0x58, 0x83, 0x2b, 0x96, 0x51, 0x69, 0x35, 0xab, 0xf6, 0xb6, 0x5e, 0xe9, 0xb4, 0xcc, 0xbc, + 0x44, 0x8c, 0x1b, 0x70, 0x3e, 0x07, 0xa7, 0xd5, 0x69, 0xab, 0x0a, 0xb9, 0x0a, 0x97, 0x72, 0xca, + 0x1e, 0x1a, 0x5b, 0xfa, 0x5e, 0x67, 0xb7, 0xa9, 0x16, 0x26, 0x10, 0x5b, 0x56, 0x4b, 0x2d, 0x6e, + 0xfe, 0x3d, 0x05, 0x96, 0xf7, 0x02, 0xfe, 0x80, 0x70, 0x0f, 0x0d, 0x76, 0xd7, 0xe0, 0xf2, 0x9e, + 0x65, 0x98, 0x76, 0xa7, 0x75, 0xdf, 0x68, 0xda, 0x7b, 0x96, 0xbe, 0x93, 0xae, 0xcd, 0x55, 0xb8, + 0x24, 0x61, 0x98, 0x46, 0xa5, 0xf5, 0xc0, 0x30, 0xed, 0xb6, 0x6e, 0x59, 0x0f, 0x5b, 0x66, 0x55, + 0x55, 0xe8, 0x17, 0x73, 0x10, 0x1a, 0xdb, 0x3a, 0xab, 0x4d, 0xa2, 0xac, 0x69, 0x3c, 0xd4, 0xeb, + 0xf6, 0x56, 0xab, 0xa3, 0x16, 0x37, 0x1b, 0xf4, 0x16, 0x81, 0xe9, 0xd0, 0xd8, 0x33, 0x8f, 0x32, + 0x94, 0x9a, 0xad, 0xa6, 0x91, 0xf6, 0xf4, 0x5a, 0x84, 0xb2, 0xde, 0x6e, 0x9b, 0xad, 0x07, 0x38, + 0x79, 0x00, 0x66, 0xab, 0x46, 0xb3, 0x86, 0xb3, 0x65, 0x11, 0xca, 0x6d, 0xb3, 0xd5, 0x68, 0x75, + 0x8c, 0xaa, 0x5a, 0xda, 0xd4, 0x61, 0x95, 0x1d, 0x09, 0x9c, 0x29, 0xaa, 0xf9, 0x97, 0x60, 0x7e, + 0xaf, 0x59, 0x35, 0xb6, 0x6b, 0x4d, 0x6c, 0xcb, 0x32, 0x80, 0xb5, 0xdb, 0x32, 0x3b, 0x76, 0xc7, + 0x30, 0x1b, 0x2c, 0xbf, 0x65, 0xbd, 0xd5, 0xdc, 0x61, 0x3f, 0x0b, 0x9b, 0xa6, 0x38, 0x9b, 0x45, + 0xbd, 0xba, 0x3e, 0xf3, 0xcc, 0xaa, 0x1a, 0xdb, 0xfa, 0x5e, 0xbd, 0xc3, 0x47, 0xf9, 0x91, 0x6d, + 0x1a, 0x5f, 0xd9, 0x33, 0xac, 0x8e, 0xa5, 0x2a, 0x44, 0x85, 0xc5, 0xa6, 0x61, 0x54, 0x2d, 0xdb, + 0x34, 0x1e, 0xd4, 0x8c, 0x87, 0x6a, 0x81, 0x56, 0x8b, 0xfd, 0x4d, 0x2b, 0xb9, 0xf9, 0x5d, 0x05, + 0x08, 0xcb, 0x46, 0x27, 0x52, 0x9c, 0xe3, 0xa4, 0xbb, 0x02, 0x1b, 0xbb, 0x74, 0xb6, 0x60, 0xef, + 0x34, 0x5a, 0xd5, 0x74, 0xaf, 0x9f, 0x07, 0x92, 0x2a, 0x6f, 0x6d, 0x6f, 0xe3, 0xca, 0x3a, 0x9b, + 0x82, 0x57, 0xcd, 0x56, 0x5b, 0x2d, 0x6c, 0x14, 0xca, 0x0a, 0xb9, 0x90, 0x29, 0xbc, 0x6f, 0x18, + 0x6d, 0xb5, 0x48, 0x47, 0x39, 0x55, 0x20, 0x56, 0x3d, 0x23, 0x2f, 0x6d, 0x7e, 0x5b, 0x81, 0xf3, + 0xac, 0x9a, 0x62, 0x0b, 0x89, 0xaa, 0x7a, 0x19, 0xd6, 0x79, 0x8e, 0xcd, 0xbc, 0x8a, 0xae, 0x81, + 0x9a, 0x28, 0x65, 0xd5, 0x3c, 0x07, 0xab, 0x09, 0x28, 0xd6, 0xa3, 0x40, 0x37, 0xc8, 0x04, 0x78, + 0xcb, 0xb0, 0x3a, 0xb6, 0xb1, 0xbd, 0x4d, 0x87, 0x04, 0x2b, 0x52, 0xdc, 0xd4, 0x60, 0xb5, 0xe2, + 0x8e, 0x42, 0xe3, 0x93, 0xd0, 0x1d, 0x04, 0x9e, 0x3f, 0xc0, 0x2a, 0x2c, 0xc1, 0xbc, 0xf1, 0x8b, + 0x1d, 0xa3, 0x69, 0xd5, 0x5a, 0x4d, 0xf5, 0xcc, 0xe6, 0xe5, 0x14, 0x8e, 0xd8, 0x0a, 0x2c, 0x6b, + 0x57, 0x3d, 0xb3, 0xe9, 0xc0, 0x92, 0x78, 0x5a, 0xc7, 0x26, 0xd6, 0x15, 0xd8, 0x10, 0xd3, 0x15, + 0xb7, 0x95, 0x74, 0x13, 0xd6, 0x61, 0x2d, 0x5b, 0x6e, 0x74, 0x54, 0x85, 0x8e, 0x42, 0xaa, 0x84, + 0xc2, 0x0b, 0x9b, 0xdf, 0x52, 0x60, 0x29, 0xb2, 0xf7, 0xe2, 0x44, 0xbb, 0x0a, 0x97, 0x1a, 0xdb, + 0xba, 0x5d, 0x35, 0x1e, 0xd4, 0x2a, 0x86, 0x7d, 0xbf, 0xd6, 0xac, 0xa6, 0x3e, 0x72, 0x11, 0xce, + 0xe5, 0x20, 0xe0, 0x57, 0xd6, 0x61, 0x2d, 0x5d, 0xd4, 0xa1, 0xab, 0xbd, 0x40, 0xbb, 0x3e, 0x5d, + 0x12, 0x2d, 0xf5, 0xe2, 0xe6, 0x03, 0x58, 0xb6, 0xf4, 0x46, 0x7d, 0xdb, 0x1f, 0x75, 0x5d, 0x7d, + 0x1c, 0x1e, 0x0e, 0xe8, 0xbe, 0xbb, 0xdd, 0x32, 0x2b, 0x86, 0x8d, 0x28, 0xa9, 0x1a, 0x9c, 0x85, + 0x15, 0xb9, 0xf0, 0x91, 0x41, 0xa7, 0x2f, 0x81, 0x65, 0x19, 0xd8, 0x6c, 0xa9, 0x85, 0xcd, 0xaf, + 0xc1, 0x22, 0x77, 0x02, 0x61, 0xfd, 0x77, 0x01, 0xce, 0xca, 0xbf, 0xdb, 0xee, 0xa0, 0xe7, 0x0d, + 0x0e, 0xd4, 0x33, 0xe9, 0x02, 0x73, 0x3c, 0x18, 0xd0, 0x02, 0xdc, 0x12, 0xe4, 0x82, 0x8e, 0x3b, + 0x3a, 0xf2, 0x06, 0x4e, 0xe8, 0xf6, 0xd4, 0xc2, 0xe6, 0x2d, 0x58, 0x4a, 0xe4, 0x57, 0xa4, 0x03, + 0x57, 0x6f, 0xf1, 0x3d, 0xbc, 0x61, 0x54, 0x6b, 0x7b, 0x0d, 0x75, 0x86, 0x6e, 0x06, 0xbb, 0xb5, + 0x9d, 0x5d, 0x15, 0x36, 0x7f, 0x5b, 0x81, 0x65, 0x9e, 0x35, 0xbd, 0xb1, 0xad, 0x8b, 0xa1, 0xa6, + 0xd3, 0x8c, 0x65, 0x6d, 0x35, 0x2c, 0x8b, 0xf9, 0x48, 0x5e, 0x86, 0x75, 0xfe, 0xc3, 0xd6, 0x9b, + 0x55, 0x7b, 0x57, 0x37, 0xab, 0x0f, 0x75, 0x93, 0xce, 0xbd, 0x47, 0x6a, 0x01, 0x17, 0x94, 0x04, + 0xb1, 0x3b, 0xad, 0xbd, 0xca, 0xae, 0x5a, 0xa4, 0xf3, 0x37, 0x01, 0x6f, 0xd7, 0x9a, 0x6a, 0x09, + 0x97, 0x67, 0x06, 0x1b, 0xd9, 0xd2, 0xf2, 0x99, 0xcd, 0x1f, 0x29, 0x70, 0xc1, 0xf2, 0x0e, 0x06, + 0x4e, 0x38, 0x1e, 0xb9, 0x7a, 0xff, 0xc0, 0x1f, 0x79, 0xe1, 0xe1, 0x91, 0x35, 0xf6, 0x42, 0x97, + 0xbc, 0x02, 0x2f, 0x5b, 0xb5, 0x9d, 0xa6, 0xde, 0xa1, 0xcb, 0x4b, 0xaf, 0xef, 0xb4, 0xcc, 0x5a, + 0x67, 0xb7, 0x61, 0x5b, 0x7b, 0xb5, 0xcc, 0xcc, 0x7b, 0x09, 0xae, 0x4d, 0x46, 0xad, 0x1b, 0x3b, + 0x7a, 0xe5, 0x91, 0xaa, 0x4c, 0x67, 0xb8, 0xa5, 0xd7, 0xf5, 0x66, 0xc5, 0xa8, 0xda, 0x0f, 0x6e, + 0xab, 0x05, 0xf2, 0x32, 0x5c, 0x9f, 0x8c, 0xba, 0x5d, 0x6b, 0x5b, 0x14, 0xad, 0x38, 0xfd, 0xbb, + 0xbb, 0x56, 0x83, 0x62, 0x95, 0x36, 0x7f, 0x4f, 0x81, 0xf5, 0x49, 0x91, 0xc6, 0xc9, 0x0d, 0xd0, + 0x8c, 0x66, 0xc7, 0xd4, 0x6b, 0x55, 0xbb, 0x62, 0x1a, 0x55, 0xa3, 0xd9, 0xa9, 0xe9, 0x75, 0xcb, + 0xb6, 0x5a, 0x7b, 0x74, 0x36, 0xc5, 0xae, 0xac, 0x2f, 0xc2, 0xd5, 0x29, 0x78, 0xad, 0x5a, 0xb5, + 0xa2, 0x2a, 0xe4, 0x36, 0xbc, 0x36, 0x05, 0xc9, 0x7a, 0x64, 0x75, 0x8c, 0x86, 0x5c, 0xa2, 0x16, + 0x70, 0xc3, 0xca, 0x0f, 0xb2, 0x4c, 0x5b, 0x87, 0x25, 0xd3, 0x2b, 0x76, 0x1d, 0x5e, 0x98, 0x88, + 0xc5, 0xab, 0xf5, 0x22, 0x5c, 0x9d, 0x88, 0xc2, 0x2a, 0xa5, 0x16, 0x36, 0x3f, 0x80, 0x8d, 0xc9, + 0x81, 0x3e, 0xe9, 0x79, 0x91, 0x1c, 0xf2, 0x32, 0x94, 0xaa, 0xf4, 0x94, 0x4b, 0x64, 0x19, 0xa6, + 0xb3, 0xd3, 0x34, 0x6a, 0x8d, 0x36, 0xdd, 0x08, 0xf9, 0xe1, 0x82, 0xa7, 0xc7, 0x37, 0x15, 0x50, + 0xd3, 0x71, 0xf1, 0x32, 0x5e, 0xd1, 0xe6, 0x5e, 0xb3, 0xc9, 0xce, 0xca, 0x15, 0x58, 0x68, 0x75, + 0x76, 0x0d, 0x93, 0x27, 0x70, 0xc6, 0x8c, 0xcd, 0x7b, 0x4d, 0xba, 0xb4, 0x5b, 0x66, 0xed, 0xab, + 0x78, 0x68, 0xae, 0xc3, 0x9a, 0x55, 0xd7, 0x2b, 0xf7, 0xed, 0x66, 0xab, 0x63, 0xd7, 0x9a, 0x76, + 0x65, 0x57, 0x6f, 0x36, 0x8d, 0xba, 0x0a, 0x74, 0xcf, 0x6e, 0xdd, 0xef, 0xe8, 0x76, 0xa5, 0xd5, + 0xdc, 0xae, 0xed, 0x70, 0x16, 0x6b, 0x38, 0x0b, 0x26, 0xc5, 0xe5, 0x20, 0x9f, 0x83, 0x9b, 0x48, + 0xd3, 0xae, 0xef, 0xed, 0xd4, 0x9a, 0xb6, 0xf5, 0xa8, 0x59, 0x11, 0x92, 0x5b, 0x25, 0x7b, 0x56, + 0xdc, 0x84, 0x97, 0xa6, 0x62, 0xc7, 0x19, 0x98, 0x6f, 0x80, 0x36, 0x15, 0x93, 0xb7, 0x6f, 0xf3, + 0x07, 0x0a, 0x5c, 0x9a, 0xe2, 0xb7, 0x43, 0x5e, 0x83, 0x57, 0x76, 0x0d, 0xbd, 0x5a, 0x37, 0x2c, + 0x0b, 0x77, 0x38, 0x3a, 0x88, 0xcc, 0xa9, 0x3a, 0xf7, 0x24, 0x78, 0x05, 0x5e, 0x9e, 0x8e, 0x1e, + 0x8b, 0x25, 0x37, 0xe1, 0xa5, 0xe9, 0xa8, 0x5c, 0x4c, 0x29, 0x90, 0x4d, 0xb8, 0x31, 0x1d, 0x33, + 0x12, 0x6f, 0x8a, 0x9b, 0xbf, 0xa1, 0xc0, 0xf9, 0x7c, 0x55, 0x39, 0xad, 0x5b, 0xad, 0x69, 0x75, + 0xf4, 0x7a, 0xdd, 0x6e, 0xeb, 0xa6, 0xde, 0xb0, 0x8d, 0xa6, 0xd9, 0xaa, 0xd7, 0xf3, 0xce, 0xe4, + 0x97, 0xe0, 0xda, 0x64, 0x54, 0xab, 0x62, 0xd6, 0xda, 0xf4, 0xd8, 0xd1, 0xe0, 0xca, 0x64, 0x2c, + 0xa3, 0x56, 0x31, 0xd4, 0xc2, 0xd6, 0xbb, 0x7f, 0xfc, 0xe7, 0x57, 0xce, 0xfc, 0xf1, 0x8f, 0xae, + 0x28, 0xff, 0xe9, 0x47, 0x57, 0x94, 0x3f, 0xfb, 0xd1, 0x15, 0xe5, 0xab, 0xaf, 0x32, 0x4f, 0xe5, + 0x5b, 0x5d, 0xff, 0xe8, 0xf5, 0x83, 0x91, 0xf3, 0xb1, 0x17, 0x3a, 0x2c, 0x65, 0xc7, 0xeb, 0xc2, + 0xd2, 0xf1, 0xba, 0x33, 0xf4, 0x5e, 0xc7, 0x8b, 0xff, 0xe3, 0x59, 0xbc, 0x41, 0xbe, 0xf9, 0xbf, + 0x03, 0x00, 0x00, 0xff, 0xff, 0x76, 0x1c, 0x38, 0xa7, 0xcb, 0xf4, 0x01, 0x00, } func (this *SSHKeyPair) Equal(that interface{}) bool { @@ -32870,6 +33172,91 @@ func (m *JWTKeyPair) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *EncryptionKeyPair) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EncryptionKeyPair) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EncryptionKeyPair) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Hash != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Hash)) + i-- + dAtA[i] = 0x20 + } + if m.PrivateKeyType != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.PrivateKeyType)) + i-- + dAtA[i] = 0x18 + } + if len(m.PrivateKey) > 0 { + i -= len(m.PrivateKey) + copy(dAtA[i:], m.PrivateKey) + i = encodeVarintTypes(dAtA, i, uint64(len(m.PrivateKey))) + i-- + dAtA[i] = 0x12 + } + if len(m.PublicKey) > 0 { + i -= len(m.PublicKey) + copy(dAtA[i:], m.PublicKey) + i = encodeVarintTypes(dAtA, i, uint64(len(m.PublicKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AgeEncryptionKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AgeEncryptionKey) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AgeEncryptionKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.PublicKey) > 0 { + i -= len(m.PublicKey) + copy(dAtA[i:], m.PublicKey) + i = encodeVarintTypes(dAtA, i, uint64(len(m.PublicKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *CertAuthorityV2) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -36118,119 +36505,339 @@ func (m *SessionRecordingConfigV2) MarshalToSizedBuffer(dAtA []byte) (int, error i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - { - size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - if len(m.Version) > 0 { - i -= len(m.Version) - copy(dAtA[i:], m.Version) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Version))) - i-- - dAtA[i] = 0x1a - } - if len(m.SubKind) > 0 { - i -= len(m.SubKind) - copy(dAtA[i:], m.SubKind) - i = encodeVarintTypes(dAtA, i, uint64(len(m.SubKind))) - i-- - dAtA[i] = 0x12 - } - if len(m.Kind) > 0 { - i -= len(m.Kind) - copy(dAtA[i:], m.Kind) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Kind))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *SessionRecordingConfigSpecV2) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SessionRecordingConfigSpecV2) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *SessionRecordingConfigSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.XXX_unrecognized != nil { - i -= len(m.XXX_unrecognized) - copy(dAtA[i:], m.XXX_unrecognized) - } - if m.ProxyChecksHostKeys != nil { + if m.Status != nil { { - size := m.ProxyChecksHostKeys.Size() - i -= size - if _, err := m.ProxyChecksHostKeys.MarshalTo(dAtA[i:]); err != nil { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { return 0, err } + i -= size i = encodeVarintTypes(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 - } - if len(m.Mode) > 0 { - i -= len(m.Mode) - copy(dAtA[i:], m.Mode) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Mode))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *AuthPreferenceV2) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AuthPreferenceV2) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AuthPreferenceV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.XXX_unrecognized != nil { - i -= len(m.XXX_unrecognized) - copy(dAtA[i:], m.XXX_unrecognized) + dAtA[i] = 0x32 + } + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x1a + } + if len(m.SubKind) > 0 { + i -= len(m.SubKind) + copy(dAtA[i:], m.SubKind) + i = encodeVarintTypes(dAtA, i, uint64(len(m.SubKind))) + i-- + dAtA[i] = 0x12 + } + if len(m.Kind) > 0 { + i -= len(m.Kind) + copy(dAtA[i:], m.Kind) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Kind))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *KeyLabel) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *KeyLabel) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *KeyLabel) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Label) > 0 { + i -= len(m.Label) + copy(dAtA[i:], m.Label) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Label))) + i-- + dAtA[i] = 0x12 + } + if len(m.Type) > 0 { + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ManualKeyManagementConfig) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ManualKeyManagementConfig) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ManualKeyManagementConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.RotatedKeys) > 0 { + for iNdEx := len(m.RotatedKeys) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.RotatedKeys[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.ActiveKeys) > 0 { + for iNdEx := len(m.ActiveKeys) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ActiveKeys[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.Enabled { + i-- + if m.Enabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *SessionRecordingEncryptionConfig) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SessionRecordingEncryptionConfig) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SessionRecordingEncryptionConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.ManualKeyManagement != nil { + { + size, err := m.ManualKeyManagement.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Enabled { + i-- + if m.Enabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *SessionRecordingConfigSpecV2) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SessionRecordingConfigSpecV2) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SessionRecordingConfigSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Encryption != nil { + { + size, err := m.Encryption.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.ProxyChecksHostKeys != nil { + { + size := m.ProxyChecksHostKeys.Size() + i -= size + if _, err := m.ProxyChecksHostKeys.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Mode) > 0 { + i -= len(m.Mode) + copy(dAtA[i:], m.Mode) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Mode))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SessionRecordingConfigStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SessionRecordingConfigStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SessionRecordingConfigStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.EncryptionKeys) > 0 { + for iNdEx := len(m.EncryptionKeys) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.EncryptionKeys[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *AuthPreferenceV2) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AuthPreferenceV2) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AuthPreferenceV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) } { size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) @@ -36315,20 +36922,20 @@ func (m *AuthPreferenceSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0xb2 } if len(m.SecondFactors) > 0 { - dAtA126 := make([]byte, len(m.SecondFactors)*10) - var j125 int + dAtA129 := make([]byte, len(m.SecondFactors)*10) + var j128 int for _, num := range m.SecondFactors { for num >= 1<<7 { - dAtA126[j125] = uint8(uint64(num)&0x7f | 0x80) + dAtA129[j128] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j125++ + j128++ } - dAtA126[j125] = uint8(num) - j125++ + dAtA129[j128] = uint8(num) + j128++ } - i -= j125 - copy(dAtA[i:], dAtA126[:j125]) - i = encodeVarintTypes(dAtA, i, uint64(j125)) + i -= j128 + copy(dAtA[i:], dAtA129[:j128]) + i = encodeVarintTypes(dAtA, i, uint64(j128)) i-- dAtA[i] = 0x1 i-- @@ -37001,12 +37608,12 @@ func (m *UserTokenSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n142, err142 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err142 != nil { - return 0, err142 + n145, err145 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err145 != nil { + return 0, err145 } - i -= n142 - i = encodeVarintTypes(dAtA, i, uint64(n142)) + i -= n145 + i = encodeVarintTypes(dAtA, i, uint64(n145)) i-- dAtA[i] = 0x22 if m.Usage != 0 { @@ -37123,12 +37730,12 @@ func (m *UserTokenSecretsSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n145, err145 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err145 != nil { - return 0, err145 + n148, err148 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err148 != nil { + return 0, err148 } - i -= n145 - i = encodeVarintTypes(dAtA, i, uint64(n145)) + i -= n148 + i = encodeVarintTypes(dAtA, i, uint64(n148)) i-- dAtA[i] = 0x1a if len(m.QRCode) > 0 { @@ -37376,12 +37983,12 @@ func (m *AccessReview) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if m.AssumeStartTime != nil { - n148, err148 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AssumeStartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AssumeStartTime):]) - if err148 != nil { - return 0, err148 + n151, err151 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AssumeStartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AssumeStartTime):]) + if err151 != nil { + return 0, err151 } - i -= n148 - i = encodeVarintTypes(dAtA, i, uint64(n148)) + i -= n151 + i = encodeVarintTypes(dAtA, i, uint64(n151)) i-- dAtA[i] = 0x52 } @@ -37398,20 +38005,20 @@ func (m *AccessReview) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x4a } if len(m.ThresholdIndexes) > 0 { - dAtA151 := make([]byte, len(m.ThresholdIndexes)*10) - var j150 int + dAtA154 := make([]byte, len(m.ThresholdIndexes)*10) + var j153 int for _, num := range m.ThresholdIndexes { for num >= 1<<7 { - dAtA151[j150] = uint8(uint64(num)&0x7f | 0x80) + dAtA154[j153] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j150++ + j153++ } - dAtA151[j150] = uint8(num) - j150++ + dAtA154[j153] = uint8(num) + j153++ } - i -= j150 - copy(dAtA[i:], dAtA151[:j150]) - i = encodeVarintTypes(dAtA, i, uint64(j150)) + i -= j153 + copy(dAtA[i:], dAtA154[:j153]) + i = encodeVarintTypes(dAtA, i, uint64(j153)) i-- dAtA[i] = 0x3a } @@ -37425,12 +38032,12 @@ func (m *AccessReview) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x32 - n153, err153 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err153 != nil { - return 0, err153 + n156, err156 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err156 != nil { + return 0, err156 } - i -= n153 - i = encodeVarintTypes(dAtA, i, uint64(n153)) + i -= n156 + i = encodeVarintTypes(dAtA, i, uint64(n156)) i-- dAtA[i] = 0x2a if len(m.Reason) > 0 { @@ -37533,20 +38140,20 @@ func (m *ThresholdIndexSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.XXX_unrecognized) } if len(m.Indexes) > 0 { - dAtA156 := make([]byte, len(m.Indexes)*10) - var j155 int + dAtA159 := make([]byte, len(m.Indexes)*10) + var j158 int for _, num := range m.Indexes { for num >= 1<<7 { - dAtA156[j155] = uint8(uint64(num)&0x7f | 0x80) + dAtA159[j158] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j155++ + j158++ } - dAtA156[j155] = uint8(num) - j155++ + dAtA159[j158] = uint8(num) + j158++ } - i -= j155 - copy(dAtA[i:], dAtA156[:j155]) - i = encodeVarintTypes(dAtA, i, uint64(j155)) + i -= j158 + copy(dAtA[i:], dAtA159[:j158]) + i = encodeVarintTypes(dAtA, i, uint64(j158)) i-- dAtA[i] = 0xa } @@ -37654,24 +38261,24 @@ func (m *AccessRequestSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0xba } if m.ResourceExpiry != nil { - n159, err159 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.ResourceExpiry, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.ResourceExpiry):]) - if err159 != nil { - return 0, err159 + n162, err162 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.ResourceExpiry, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.ResourceExpiry):]) + if err162 != nil { + return 0, err162 } - i -= n159 - i = encodeVarintTypes(dAtA, i, uint64(n159)) + i -= n162 + i = encodeVarintTypes(dAtA, i, uint64(n162)) i-- dAtA[i] = 0x1 i-- dAtA[i] = 0xb2 } if m.AssumeStartTime != nil { - n160, err160 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AssumeStartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AssumeStartTime):]) - if err160 != nil { - return 0, err160 + n163, err163 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.AssumeStartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.AssumeStartTime):]) + if err163 != nil { + return 0, err163 } - i -= n160 - i = encodeVarintTypes(dAtA, i, uint64(n160)) + i -= n163 + i = encodeVarintTypes(dAtA, i, uint64(n163)) i-- dAtA[i] = 0x1 i-- @@ -37691,22 +38298,22 @@ func (m *AccessRequestSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0xa2 } - n162, err162 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.SessionTTL, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.SessionTTL):]) - if err162 != nil { - return 0, err162 + n165, err165 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.SessionTTL, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.SessionTTL):]) + if err165 != nil { + return 0, err165 } - i -= n162 - i = encodeVarintTypes(dAtA, i, uint64(n162)) + i -= n165 + i = encodeVarintTypes(dAtA, i, uint64(n165)) i-- dAtA[i] = 0x1 i-- dAtA[i] = 0x92 - n163, err163 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.MaxDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.MaxDuration):]) - if err163 != nil { - return 0, err163 + n166, err166 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.MaxDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.MaxDuration):]) + if err166 != nil { + return 0, err166 } - i -= n163 - i = encodeVarintTypes(dAtA, i, uint64(n163)) + i -= n166 + i = encodeVarintTypes(dAtA, i, uint64(n166)) i-- dAtA[i] = 0x1 i-- @@ -37839,20 +38446,20 @@ func (m *AccessRequestSpecV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n167, err167 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err167 != nil { - return 0, err167 + n170, err170 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err170 != nil { + return 0, err170 } - i -= n167 - i = encodeVarintTypes(dAtA, i, uint64(n167)) + i -= n170 + i = encodeVarintTypes(dAtA, i, uint64(n170)) i-- dAtA[i] = 0x2a - n168, err168 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err168 != nil { - return 0, err168 + n171, err171 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err171 != nil { + return 0, err171 } - i -= n168 - i = encodeVarintTypes(dAtA, i, uint64(n168)) + i -= n171 + i = encodeVarintTypes(dAtA, i, uint64(n171)) i-- dAtA[i] = 0x22 if m.State != 0 { @@ -38856,12 +39463,12 @@ func (m *RoleOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0xfa } - n182, err182 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MFAVerificationInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MFAVerificationInterval):]) - if err182 != nil { - return 0, err182 + n185, err185 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MFAVerificationInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MFAVerificationInterval):]) + if err185 != nil { + return 0, err185 } - i -= n182 - i = encodeVarintTypes(dAtA, i, uint64(n182)) + i -= n185 + i = encodeVarintTypes(dAtA, i, uint64(n185)) i-- dAtA[i] = 0x1 i-- @@ -41058,12 +41665,12 @@ func (m *UserSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x42 - n215, err215 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err215 != nil { - return 0, err215 + n218, err218 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err218 != nil { + return 0, err218 } - i -= n215 - i = encodeVarintTypes(dAtA, i, uint64(n215)) + i -= n218 + i = encodeVarintTypes(dAtA, i, uint64(n218)) i-- dAtA[i] = 0x3a { @@ -41219,20 +41826,20 @@ func (m *LoginStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n218, err218 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockExpires):]) - if err218 != nil { - return 0, err218 + n221, err221 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockExpires):]) + if err221 != nil { + return 0, err221 } - i -= n218 - i = encodeVarintTypes(dAtA, i, uint64(n218)) + i -= n221 + i = encodeVarintTypes(dAtA, i, uint64(n221)) i-- dAtA[i] = 0x22 - n219, err219 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockedTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockedTime):]) - if err219 != nil { - return 0, err219 + n222, err222 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LockedTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LockedTime):]) + if err222 != nil { + return 0, err222 } - i -= n219 - i = encodeVarintTypes(dAtA, i, uint64(n219)) + i -= n222 + i = encodeVarintTypes(dAtA, i, uint64(n222)) i-- dAtA[i] = 0x1a if len(m.LockedMessage) > 0 { @@ -41289,12 +41896,12 @@ func (m *CreatedBy) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x1a - n221, err221 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) - if err221 != nil { - return 0, err221 + n224, err224 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err224 != nil { + return 0, err224 } - i -= n221 - i = encodeVarintTypes(dAtA, i, uint64(n221)) + i -= n224 + i = encodeVarintTypes(dAtA, i, uint64(n224)) i-- dAtA[i] = 0x12 if m.Connector != nil { @@ -41412,20 +42019,20 @@ func (m *MFADevice) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } } - n224, err224 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUsed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUsed):]) - if err224 != nil { - return 0, err224 + n227, err227 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastUsed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastUsed):]) + if err227 != nil { + return 0, err227 } - i -= n224 - i = encodeVarintTypes(dAtA, i, uint64(n224)) + i -= n227 + i = encodeVarintTypes(dAtA, i, uint64(n227)) i-- dAtA[i] = 0x3a - n225, err225 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.AddedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.AddedAt):]) - if err225 != nil { - return 0, err225 + n228, err228 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.AddedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.AddedAt):]) + if err228 != nil { + return 0, err228 } - i -= n225 - i = encodeVarintTypes(dAtA, i, uint64(n225)) + i -= n228 + i = encodeVarintTypes(dAtA, i, uint64(n228)) i-- dAtA[i] = 0x32 if len(m.Id) > 0 { @@ -42122,12 +42729,12 @@ func (m *TunnelConnectionSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x22 } - n237, err237 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) - if err237 != nil { - return 0, err237 + n240, err240 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) + if err240 != nil { + return 0, err240 } - i -= n237 - i = encodeVarintTypes(dAtA, i, uint64(n237)) + i -= n240 + i = encodeVarintTypes(dAtA, i, uint64(n240)) i-- dAtA[i] = 0x1a if len(m.ProxyName) > 0 { @@ -42219,12 +42826,12 @@ func (m *AcquireSemaphoreRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x2a } - n238, err238 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err238 != nil { - return 0, err238 + n241, err241 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err241 != nil { + return 0, err241 } - i -= n238 - i = encodeVarintTypes(dAtA, i, uint64(n238)) + i -= n241 + i = encodeVarintTypes(dAtA, i, uint64(n241)) i-- dAtA[i] = 0x22 if m.MaxLeases != 0 { @@ -42273,12 +42880,12 @@ func (m *SemaphoreLease) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n239, err239 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err239 != nil { - return 0, err239 + n242, err242 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err242 != nil { + return 0, err242 } - i -= n239 - i = encodeVarintTypes(dAtA, i, uint64(n239)) + i -= n242 + i = encodeVarintTypes(dAtA, i, uint64(n242)) i-- dAtA[i] = 0x2a if len(m.LeaseID) > 0 { @@ -42336,12 +42943,12 @@ func (m *SemaphoreLeaseRef) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - n240, err240 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err240 != nil { - return 0, err240 + n243, err243 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err243 != nil { + return 0, err243 } - i -= n240 - i = encodeVarintTypes(dAtA, i, uint64(n240)) + i -= n243 + i = encodeVarintTypes(dAtA, i, uint64(n243)) i-- dAtA[i] = 0x12 if len(m.LeaseID) > 0 { @@ -42613,28 +43220,28 @@ func (m *WebSessionSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x48 } - n247, err247 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LoginTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LoginTime):]) - if err247 != nil { - return 0, err247 + n250, err250 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LoginTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LoginTime):]) + if err250 != nil { + return 0, err250 } - i -= n247 - i = encodeVarintTypes(dAtA, i, uint64(n247)) + i -= n250 + i = encodeVarintTypes(dAtA, i, uint64(n250)) i-- dAtA[i] = 0x42 - n248, err248 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err248 != nil { - return 0, err248 + n251, err251 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err251 != nil { + return 0, err251 } - i -= n248 - i = encodeVarintTypes(dAtA, i, uint64(n248)) + i -= n251 + i = encodeVarintTypes(dAtA, i, uint64(n251)) i-- dAtA[i] = 0x3a - n249, err249 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.BearerTokenExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.BearerTokenExpires):]) - if err249 != nil { - return 0, err249 + n252, err252 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.BearerTokenExpires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.BearerTokenExpires):]) + if err252 != nil { + return 0, err252 } - i -= n249 - i = encodeVarintTypes(dAtA, i, uint64(n249)) + i -= n252 + i = encodeVarintTypes(dAtA, i, uint64(n252)) i-- dAtA[i] = 0x32 if len(m.BearerToken) > 0 { @@ -42867,20 +43474,20 @@ func (m *SAMLSessionData) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - n250, err250 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExpireTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ExpireTime):]) - if err250 != nil { - return 0, err250 + n253, err253 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.ExpireTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.ExpireTime):]) + if err253 != nil { + return 0, err253 } - i -= n250 - i = encodeVarintTypes(dAtA, i, uint64(n250)) + i -= n253 + i = encodeVarintTypes(dAtA, i, uint64(n253)) i-- dAtA[i] = 0x1a - n251, err251 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreateTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreateTime):]) - if err251 != nil { - return 0, err251 + n254, err254 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreateTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreateTime):]) + if err254 != nil { + return 0, err254 } - i -= n251 - i = encodeVarintTypes(dAtA, i, uint64(n251)) + i -= n254 + i = encodeVarintTypes(dAtA, i, uint64(n254)) i-- dAtA[i] = 0x12 if len(m.ID) > 0 { @@ -43162,12 +43769,12 @@ func (m *RemoteClusterStatusV3) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n255, err255 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) - if err255 != nil { - return 0, err255 + n258, err258 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastHeartbeat, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastHeartbeat):]) + if err258 != nil { + return 0, err258 } - i -= n255 - i = encodeVarintTypes(dAtA, i, uint64(n255)) + i -= n258 + i = encodeVarintTypes(dAtA, i, uint64(n258)) i-- dAtA[i] = 0x12 if len(m.Connection) > 0 { @@ -46066,12 +46673,12 @@ func (m *GithubAuthRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x62 } if m.Expires != nil { - n294, err294 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err294 != nil { - return 0, err294 + n297, err297 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err297 != nil { + return 0, err297 } - i -= n294 - i = encodeVarintTypes(dAtA, i, uint64(n294)) + i -= n297 + i = encodeVarintTypes(dAtA, i, uint64(n297)) i-- dAtA[i] = 0x5a } @@ -47083,21 +47690,21 @@ func (m *LockSpecV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x2a } - n312, err312 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt):]) - if err312 != nil { - return 0, err312 + n315, err315 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt):]) + if err315 != nil { + return 0, err315 } - i -= n312 - i = encodeVarintTypes(dAtA, i, uint64(n312)) + i -= n315 + i = encodeVarintTypes(dAtA, i, uint64(n315)) i-- dAtA[i] = 0x22 if m.Expires != nil { - n313, err313 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err313 != nil { - return 0, err313 + n316, err316 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err316 != nil { + return 0, err316 } - i -= n313 - i = encodeVarintTypes(dAtA, i, uint64(n313)) + i -= n316 + i = encodeVarintTypes(dAtA, i, uint64(n316)) i-- dAtA[i] = 0x1a } @@ -47828,12 +48435,12 @@ func (m *RegisterUsingTokenRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro dAtA[i] = 0x6a } if m.Expires != nil { - n325, err325 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) - if err325 != nil { - return 0, err325 + n328, err328 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Expires):]) + if err328 != nil { + return 0, err328 } - i -= n325 - i = encodeVarintTypes(dAtA, i, uint64(n325)) + i -= n328 + i = encodeVarintTypes(dAtA, i, uint64(n328)) i-- dAtA[i] = 0x62 } @@ -48013,12 +48620,12 @@ func (m *RecoveryCodesSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n328, err328 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err328 != nil { - return 0, err328 + n331, err331 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err331 != nil { + return 0, err331 } - i -= n328 - i = encodeVarintTypes(dAtA, i, uint64(n328)) + i -= n331 + i = encodeVarintTypes(dAtA, i, uint64(n331)) i-- dAtA[i] = 0x12 if len(m.Codes) > 0 { @@ -48398,20 +49005,20 @@ func (m *SessionTrackerSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n332, err332 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err332 != nil { - return 0, err332 + n335, err335 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err335 != nil { + return 0, err335 } - i -= n332 - i = encodeVarintTypes(dAtA, i, uint64(n332)) + i -= n335 + i = encodeVarintTypes(dAtA, i, uint64(n335)) i-- dAtA[i] = 0x2a - n333, err333 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err333 != nil { - return 0, err333 + n336, err336 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err336 != nil { + return 0, err336 } - i -= n333 - i = encodeVarintTypes(dAtA, i, uint64(n333)) + i -= n336 + i = encodeVarintTypes(dAtA, i, uint64(n336)) i-- dAtA[i] = 0x22 if m.State != 0 { @@ -48515,12 +49122,12 @@ func (m *Participant) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n334, err334 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastActive, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastActive):]) - if err334 != nil { - return 0, err334 + n337, err337 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastActive, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastActive):]) + if err337 != nil { + return 0, err337 } - i -= n334 - i = encodeVarintTypes(dAtA, i, uint64(n334)) + i -= n337 + i = encodeVarintTypes(dAtA, i, uint64(n337)) i-- dAtA[i] = 0x22 if len(m.Mode) > 0 { @@ -49232,12 +49839,12 @@ func (m *ClusterAlertSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n347, err347 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err347 != nil { - return 0, err347 + n350, err350 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err350 != nil { + return 0, err350 } - i -= n347 - i = encodeVarintTypes(dAtA, i, uint64(n347)) + i -= n350 + i = encodeVarintTypes(dAtA, i, uint64(n350)) i-- dAtA[i] = 0x1a if len(m.Message) > 0 { @@ -49367,12 +49974,12 @@ func (m *AlertAcknowledgement) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n348, err348 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err348 != nil { - return 0, err348 + n351, err351 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err351 != nil { + return 0, err351 } - i -= n348 - i = encodeVarintTypes(dAtA, i, uint64(n348)) + i -= n351 + i = encodeVarintTypes(dAtA, i, uint64(n351)) i-- dAtA[i] = 0x22 if len(m.Reason) > 0 { @@ -50147,12 +50754,12 @@ func (m *PluginGithubSettings) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n373, err373 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartDate):]) - if err373 != nil { - return 0, err373 + n376, err376 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartDate, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartDate):]) + if err376 != nil { + return 0, err376 } - i -= n373 - i = encodeVarintTypes(dAtA, i, uint64(n373)) + i -= n376 + i = encodeVarintTypes(dAtA, i, uint64(n376)) i-- dAtA[i] = 0x22 if len(m.OrganizationName) > 0 { @@ -52319,12 +52926,12 @@ func (m *PluginStatusV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n390, err390 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastSyncTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastSyncTime):]) - if err390 != nil { - return 0, err390 + n393, err393 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastSyncTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastSyncTime):]) + if err393 != nil { + return 0, err393 } - i -= n390 - i = encodeVarintTypes(dAtA, i, uint64(n390)) + i -= n393 + i = encodeVarintTypes(dAtA, i, uint64(n393)) i-- dAtA[i] = 0x1a if len(m.ErrorMessage) > 0 { @@ -52774,22 +53381,22 @@ func (m *PluginOktaStatusDetailsAppGroupSync) MarshalToSizedBuffer(dAtA []byte) dAtA[i] = 0x28 } if m.LastFailed != nil { - n402, err402 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) - if err402 != nil { - return 0, err402 + n405, err405 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) + if err405 != nil { + return 0, err405 } - i -= n402 - i = encodeVarintTypes(dAtA, i, uint64(n402)) + i -= n405 + i = encodeVarintTypes(dAtA, i, uint64(n405)) i-- dAtA[i] = 0x22 } if m.LastSuccessful != nil { - n403, err403 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) - if err403 != nil { - return 0, err403 + n406, err406 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) + if err406 != nil { + return 0, err406 } - i -= n403 - i = encodeVarintTypes(dAtA, i, uint64(n403)) + i -= n406 + i = encodeVarintTypes(dAtA, i, uint64(n406)) i-- dAtA[i] = 0x1a } @@ -52848,22 +53455,22 @@ func (m *PluginOktaStatusDetailsUsersSync) MarshalToSizedBuffer(dAtA []byte) (in dAtA[i] = 0x28 } if m.LastFailed != nil { - n404, err404 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) - if err404 != nil { - return 0, err404 + n407, err407 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) + if err407 != nil { + return 0, err407 } - i -= n404 - i = encodeVarintTypes(dAtA, i, uint64(n404)) + i -= n407 + i = encodeVarintTypes(dAtA, i, uint64(n407)) i-- dAtA[i] = 0x22 } if m.LastSuccessful != nil { - n405, err405 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) - if err405 != nil { - return 0, err405 + n408, err408 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) + if err408 != nil { + return 0, err408 } - i -= n405 - i = encodeVarintTypes(dAtA, i, uint64(n405)) + i -= n408 + i = encodeVarintTypes(dAtA, i, uint64(n408)) i-- dAtA[i] = 0x1a } @@ -52982,22 +53589,22 @@ func (m *PluginOktaStatusDetailsAccessListsSync) MarshalToSizedBuffer(dAtA []byt } } if m.LastFailed != nil { - n406, err406 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) - if err406 != nil { - return 0, err406 + n409, err409 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) + if err409 != nil { + return 0, err409 } - i -= n406 - i = encodeVarintTypes(dAtA, i, uint64(n406)) + i -= n409 + i = encodeVarintTypes(dAtA, i, uint64(n409)) i-- dAtA[i] = 0x22 } if m.LastSuccessful != nil { - n407, err407 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) - if err407 != nil { - return 0, err407 + n410, err410 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) + if err410 != nil { + return 0, err410 } - i -= n407 - i = encodeVarintTypes(dAtA, i, uint64(n407)) + i -= n410 + i = encodeVarintTypes(dAtA, i, uint64(n410)) i-- dAtA[i] = 0x1a } @@ -53051,22 +53658,22 @@ func (m *PluginOktaStatusSystemLogExporter) MarshalToSizedBuffer(dAtA []byte) (i dAtA[i] = 0x4a } if m.LastFailed != nil { - n408, err408 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) - if err408 != nil { - return 0, err408 + n411, err411 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastFailed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastFailed):]) + if err411 != nil { + return 0, err411 } - i -= n408 - i = encodeVarintTypes(dAtA, i, uint64(n408)) + i -= n411 + i = encodeVarintTypes(dAtA, i, uint64(n411)) i-- dAtA[i] = 0x22 } if m.LastSuccessful != nil { - n409, err409 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) - if err409 != nil { - return 0, err409 + n412, err412 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastSuccessful, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastSuccessful):]) + if err412 != nil { + return 0, err412 } - i -= n409 - i = encodeVarintTypes(dAtA, i, uint64(n409)) + i -= n412 + i = encodeVarintTypes(dAtA, i, uint64(n412)) i-- dAtA[i] = 0x1a } @@ -53232,12 +53839,12 @@ func (m *PluginOAuth2AccessTokenCredentials) MarshalToSizedBuffer(dAtA []byte) ( i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n414, err414 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) - if err414 != nil { - return 0, err414 + n417, err417 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expires, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expires):]) + if err417 != nil { + return 0, err417 } - i -= n414 - i = encodeVarintTypes(dAtA, i, uint64(n414)) + i -= n417 + i = encodeVarintTypes(dAtA, i, uint64(n417)) i-- dAtA[i] = 0x1a if len(m.RefreshToken) > 0 { @@ -54195,20 +54802,20 @@ func (m *ScheduledAgentUpgradeWindow) MarshalToSizedBuffer(dAtA []byte) (int, er i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - n429, err429 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Stop, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Stop):]) - if err429 != nil { - return 0, err429 + n432, err432 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Stop, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Stop):]) + if err432 != nil { + return 0, err432 } - i -= n429 - i = encodeVarintTypes(dAtA, i, uint64(n429)) + i -= n432 + i = encodeVarintTypes(dAtA, i, uint64(n432)) i-- dAtA[i] = 0x12 - n430, err430 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Start):]) - if err430 != nil { - return 0, err430 + n433, err433 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Start, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Start):]) + if err433 != nil { + return 0, err433 } - i -= n430 - i = encodeVarintTypes(dAtA, i, uint64(n430)) + i -= n433 + i = encodeVarintTypes(dAtA, i, uint64(n433)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -54635,12 +55242,12 @@ func (m *OktaAssignmentSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x30 } - n437, err437 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastTransition, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastTransition):]) - if err437 != nil { - return 0, err437 + n440, err440 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastTransition, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastTransition):]) + if err440 != nil { + return 0, err440 } - i -= n437 - i = encodeVarintTypes(dAtA, i, uint64(n437)) + i -= n440 + i = encodeVarintTypes(dAtA, i, uint64(n440)) i-- dAtA[i] = 0x2a if m.Status != 0 { @@ -54648,12 +55255,12 @@ func (m *OktaAssignmentSpecV1) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x20 } - n438, err438 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CleanupTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CleanupTime):]) - if err438 != nil { - return 0, err438 + n441, err441 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CleanupTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CleanupTime):]) + if err441 != nil { + return 0, err441 } - i -= n438 - i = encodeVarintTypes(dAtA, i, uint64(n438)) + i -= n441 + i = encodeVarintTypes(dAtA, i, uint64(n441)) i-- dAtA[i] = 0x1a if len(m.Targets) > 0 { @@ -55268,20 +55875,20 @@ func (m *AWSRolesAnywhereProfileSyncIterationSummary) MarshalToSizedBuffer(dAtA i-- dAtA[i] = 0x1a } - n450, err450 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) - if err450 != nil { - return 0, err450 + n453, err453 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) + if err453 != nil { + return 0, err453 } - i -= n450 - i = encodeVarintTypes(dAtA, i, uint64(n450)) + i -= n453 + i = encodeVarintTypes(dAtA, i, uint64(n453)) i-- dAtA[i] = 0x12 - n451, err451 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) - if err451 != nil { - return 0, err451 + n454, err454 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) + if err454 != nil { + return 0, err454 } - i -= n451 - i = encodeVarintTypes(dAtA, i, uint64(n451)) + i -= n454 + i = encodeVarintTypes(dAtA, i, uint64(n454)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -56457,12 +57064,12 @@ func (m *AccessGraphSync) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x1a } } - n470, err470 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.PollInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval):]) - if err470 != nil { - return 0, err470 + n473, err473 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.PollInterval, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.PollInterval):]) + if err473 != nil { + return 0, err473 } - i -= n470 - i = encodeVarintTypes(dAtA, i, uint64(n470)) + i -= n473 + i = encodeVarintTypes(dAtA, i, uint64(n473)) i-- dAtA[i] = 0x12 if len(m.AWS) > 0 { @@ -56677,12 +57284,12 @@ func (m *TargetHealth) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x2a } if m.TransitionTimestamp != nil { - n473, err473 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.TransitionTimestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.TransitionTimestamp):]) - if err473 != nil { - return 0, err473 + n476, err476 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.TransitionTimestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.TransitionTimestamp):]) + if err476 != nil { + return 0, err476 } - i -= n473 - i = encodeVarintTypes(dAtA, i, uint64(n473)) + i -= n476 + i = encodeVarintTypes(dAtA, i, uint64(n476)) i-- dAtA[i] = 0x22 } @@ -58449,6 +59056,48 @@ func (m *JWTKeyPair) Size() (n int) { return n } +func (m *EncryptionKeyPair) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PublicKey) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.PrivateKey) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.PrivateKeyType != 0 { + n += 1 + sovTypes(uint64(m.PrivateKeyType)) + } + if m.Hash != 0 { + n += 1 + sovTypes(uint64(m.Hash)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *AgeEncryptionKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PublicKey) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *CertAuthorityV2) Size() (n int) { if m == nil { return 0 @@ -59952,6 +60601,76 @@ func (m *SessionRecordingConfigV2) Size() (n int) { n += 1 + l + sovTypes(uint64(l)) l = m.Spec.Size() n += 1 + l + sovTypes(uint64(l)) + if m.Status != nil { + l = m.Status.Size() + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *KeyLabel) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Type) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Label) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ManualKeyManagementConfig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Enabled { + n += 2 + } + if len(m.ActiveKeys) > 0 { + for _, e := range m.ActiveKeys { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.RotatedKeys) > 0 { + for _, e := range m.RotatedKeys { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *SessionRecordingEncryptionConfig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Enabled { + n += 2 + } + if m.ManualKeyManagement != nil { + l = m.ManualKeyManagement.Size() + n += 1 + l + sovTypes(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -59972,6 +60691,28 @@ func (m *SessionRecordingConfigSpecV2) Size() (n int) { l = m.ProxyChecksHostKeys.Size() n += 1 + l + sovTypes(uint64(l)) } + if m.Encryption != nil { + l = m.Encryption.Size() + n += 1 + l + sovTypes(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *SessionRecordingConfigStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.EncryptionKeys) > 0 { + for _, e := range m.EncryptionKeys { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -81196,7 +81937,7 @@ func (m *JWTKeyPair) Unmarshal(dAtA []byte) error { } return nil } -func (m *CertAuthorityV2) Unmarshal(dAtA []byte) error { +func (m *EncryptionKeyPair) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -81219,17 +81960,17 @@ func (m *CertAuthorityV2) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CertAuthorityV2: wiretype end group for non-group") + return fmt.Errorf("proto: EncryptionKeyPair: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CertAuthorityV2: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EncryptionKeyPair: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -81239,29 +81980,31 @@ func (m *CertAuthorityV2) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - m.Kind = string(dAtA[iNdEx:postIndex]) + m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...) + if m.PublicKey == nil { + m.PublicKey = []byte{} + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SubKind", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PrivateKey", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -81271,29 +82014,31 @@ func (m *CertAuthorityV2) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthTypes } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthTypes } if postIndex > l { return io.ErrUnexpectedEOF } - m.SubKind = string(dAtA[iNdEx:postIndex]) + m.PrivateKey = append(m.PrivateKey[:0], dAtA[iNdEx:postIndex]...) + if m.PrivateKey == nil { + m.PrivateKey = []byte{} + } iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PrivateKeyType", wireType) } - var stringLen uint64 + m.PrivateKeyType = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -81303,62 +82048,16 @@ func (m *CertAuthorityV2) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.PrivateKeyType |= PrivateKeyType(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Version = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) } - var msglen int + m.Hash = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -81368,25 +82067,309 @@ func (m *CertAuthorityV2) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.Hash |= uint32(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AgeEncryptionKey) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AgeEncryptionKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AgeEncryptionKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...) + if m.PublicKey == nil { + m.PublicKey = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CertAuthorityV2) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CertAuthorityV2: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CertAuthorityV2: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubKind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SubKind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -90599,6 +91582,403 @@ func (m *SessionRecordingConfigV2) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Status == nil { + m.Status = &SessionRecordingConfigStatus{} + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *KeyLabel) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: KeyLabel: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KeyLabel: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Label", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Label = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ManualKeyManagementConfig) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ManualKeyManagementConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ManualKeyManagementConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Enabled = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ActiveKeys", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ActiveKeys = append(m.ActiveKeys, &KeyLabel{}) + if err := m.ActiveKeys[len(m.ActiveKeys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RotatedKeys", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RotatedKeys = append(m.RotatedKeys, &KeyLabel{}) + if err := m.RotatedKeys[len(m.RotatedKeys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SessionRecordingEncryptionConfig) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SessionRecordingEncryptionConfig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SessionRecordingEncryptionConfig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Enabled = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ManualKeyManagement", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ManualKeyManagement == nil { + m.ManualKeyManagement = &ManualKeyManagementConfig{} + } + if err := m.ManualKeyManagement.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -90718,6 +92098,127 @@ func (m *SessionRecordingConfigSpecV2) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Encryption", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Encryption == nil { + m.Encryption = &SessionRecordingEncryptionConfig{} + } + if err := m.Encryption.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SessionRecordingConfigStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SessionRecordingConfigStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SessionRecordingConfigStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKeys", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptionKeys = append(m.EncryptionKeys, &AgeEncryptionKey{}) + if err := m.EncryptionKeys[len(m.EncryptionKeys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) diff --git a/api/utils/keys/privatekey.go b/api/utils/keys/privatekey.go index fbc745a59f36b..cc7339ecc7bf1 100644 --- a/api/utils/keys/privatekey.go +++ b/api/utils/keys/privatekey.go @@ -55,6 +55,7 @@ type cryptoPublicKeyI interface { // custom implementation for a non-standard private key, such as a hardware key. type PrivateKey struct { crypto.Signer + // sshPub is the public key in ssh.PublicKey form. sshPub ssh.PublicKey // keyPEM is PEM-encoded private key data which can be parsed with ParsePrivateKey. @@ -395,6 +396,21 @@ func MarshalPrivateKey(key crypto.Signer) ([]byte, error) { } } +// MarshalDecrypter will return a PEM encoded crypto.Decrypter. +// [key] must be an *rsa.PrivateKey +func MarshalDecrypter(key crypto.Decrypter) ([]byte, error) { + switch privateKey := key.(type) { + case *rsa.PrivateKey: + privPEM := pem.EncodeToMemory(&pem.Block{ + Type: PKCS1PrivateKeyType, + Bytes: x509.MarshalPKCS1PrivateKey(privateKey), + }) + return privPEM, nil + default: + return nil, trace.BadParameter("unsupported private key type %T", key) + } +} + // LoadKeyPair returns the PrivateKey for the given private and public key files. func LoadKeyPair(privFile, sshPubFile string, opts ...ParsePrivateKeyOpt) (*PrivateKey, error) { privPEM, err := os.ReadFile(privFile) diff --git a/constants.go b/constants.go index d2ebe3d7d38ba..1188b28db56c0 100644 --- a/constants.go +++ b/constants.go @@ -301,6 +301,9 @@ const ( // ComponentMCP represents the MCP server handler. ComponentMCP = "mcp" + // ComponentRecordingEncryption represents recording encryption + ComponentRecordingEncryption = "recording-encryption" + // VerboseLogsEnvVar forces all logs to be verbose (down to DEBUG level) VerboseLogsEnvVar = "TELEPORT_DEBUG" diff --git a/docs/pages/reference/terraform-provider/data-sources/session_recording_config.mdx b/docs/pages/reference/terraform-provider/data-sources/session_recording_config.mdx index 856b90aebd926..74f3254dd40fc 100644 --- a/docs/pages/reference/terraform-provider/data-sources/session_recording_config.mdx +++ b/docs/pages/reference/terraform-provider/data-sources/session_recording_config.mdx @@ -25,6 +25,7 @@ labels: - `metadata` (Attributes) Metadata is resource metadata (see [below for nested schema](#nested-schema-for-metadata)) - `spec` (Attributes) Spec is a SessionRecordingConfig specification (see [below for nested schema](#nested-schema-for-spec)) +- `status` (Attributes) Status is the SessionRecordingConfig status containing active encryption keys (see [below for nested schema](#nested-schema-for-status)) - `sub_kind` (String) SubKind is an optional resource sub kind, used in some resources ### Nested Schema for `metadata` @@ -40,6 +41,53 @@ Optional: Optional: +- `encryption` (Attributes) Encryption configures if and how session recordings should be encrypted. (see [below for nested schema](#nested-schema-for-specencryption)) - `mode` (String) Mode controls where (or if) the session is recorded. - `proxy_checks_host_keys` (Boolean) ProxyChecksHostKeys is used to control if the proxy will check host keys when in recording mode. +### Nested Schema for `spec.encryption` + +Optional: + +- `enabled` (Boolean) Enabled controls whether or not session recordings should be encrypted. +- `manual_key_management` (Attributes) ManualKeyManagement defines whether or not recording encryption keys should be managed externally and how to query those keys. (see [below for nested schema](#nested-schema-for-specencryptionmanual_key_management)) + +### Nested Schema for `spec.encryption.manual_key_management` + +Optional: + +- `active_keys` (Attributes List) ActiveKeys describe which keys should be queried for active recording encryption and replay. (see [below for nested schema](#nested-schema-for-specencryptionmanual_key_managementactive_keys)) +- `enabled` (Boolean) Enabled controls whether or recording encryption keys should be managed externally. +- `rotated_keys` (Attributes List) RotatedKeys describe which keys should be queried for historical replay. (see [below for nested schema](#nested-schema-for-specencryptionmanual_key_managementrotated_keys)) + +### Nested Schema for `spec.encryption.manual_key_management.active_keys` + +Optional: + +- `label` (String) Label is a value that can be used with the related keystore in order to find relevant keys. +- `type` (String) Type represents which keystore should be searched when looking up keys by label. + + +### Nested Schema for `spec.encryption.manual_key_management.rotated_keys` + +Optional: + +- `label` (String) Label is a value that can be used with the related keystore in order to find relevant keys. +- `type` (String) Type represents which keystore should be searched when looking up keys by label. + + + + + +### Nested Schema for `status` + +Optional: + +- `encryption_keys` (Attributes List) EncryptionKeys contain the currently active age encryption keys used for encrypted session recording. (see [below for nested schema](#nested-schema-for-statusencryption_keys)) + +### Nested Schema for `status.encryption_keys` + +Optional: + +- `public_key` (String) A PKIX ASN.1 DER encoded public key used for key wrapping during age encryption. Expected to be RSA 4096. + diff --git a/docs/pages/reference/terraform-provider/resources/session_recording_config.mdx b/docs/pages/reference/terraform-provider/resources/session_recording_config.mdx index a4cd43bedb8a4..2a534ffd0d05e 100644 --- a/docs/pages/reference/terraform-provider/resources/session_recording_config.mdx +++ b/docs/pages/reference/terraform-provider/resources/session_recording_config.mdx @@ -47,6 +47,7 @@ resource "teleport_session_recording_config" "example" { - `metadata` (Attributes) Metadata is resource metadata (see [below for nested schema](#nested-schema-for-metadata)) - `spec` (Attributes) Spec is a SessionRecordingConfig specification (see [below for nested schema](#nested-schema-for-spec)) +- `status` (Attributes) Status is the SessionRecordingConfig status containing active encryption keys (see [below for nested schema](#nested-schema-for-status)) - `sub_kind` (String) SubKind is an optional resource sub kind, used in some resources ### Nested Schema for `metadata` @@ -62,5 +63,52 @@ Optional: Optional: +- `encryption` (Attributes) Encryption configures if and how session recordings should be encrypted. (see [below for nested schema](#nested-schema-for-specencryption)) - `mode` (String) Mode controls where (or if) the session is recorded. - `proxy_checks_host_keys` (Boolean) ProxyChecksHostKeys is used to control if the proxy will check host keys when in recording mode. + +### Nested Schema for `spec.encryption` + +Optional: + +- `enabled` (Boolean) Enabled controls whether or not session recordings should be encrypted. +- `manual_key_management` (Attributes) ManualKeyManagement defines whether or not recording encryption keys should be managed externally and how to query those keys. (see [below for nested schema](#nested-schema-for-specencryptionmanual_key_management)) + +### Nested Schema for `spec.encryption.manual_key_management` + +Optional: + +- `active_keys` (Attributes List) ActiveKeys describe which keys should be queried for active recording encryption and replay. (see [below for nested schema](#nested-schema-for-specencryptionmanual_key_managementactive_keys)) +- `enabled` (Boolean) Enabled controls whether or recording encryption keys should be managed externally. +- `rotated_keys` (Attributes List) RotatedKeys describe which keys should be queried for historical replay. (see [below for nested schema](#nested-schema-for-specencryptionmanual_key_managementrotated_keys)) + +### Nested Schema for `spec.encryption.manual_key_management.active_keys` + +Optional: + +- `label` (String) Label is a value that can be used with the related keystore in order to find relevant keys. +- `type` (String) Type represents which keystore should be searched when looking up keys by label. + + +### Nested Schema for `spec.encryption.manual_key_management.rotated_keys` + +Optional: + +- `label` (String) Label is a value that can be used with the related keystore in order to find relevant keys. +- `type` (String) Type represents which keystore should be searched when looking up keys by label. + + + + + +### Nested Schema for `status` + +Optional: + +- `encryption_keys` (Attributes List) EncryptionKeys contain the currently active age encryption keys used for encrypted session recording. (see [below for nested schema](#nested-schema-for-statusencryption_keys)) + +### Nested Schema for `status.encryption_keys` + +Optional: + +- `public_key` (String) A PKIX ASN.1 DER encoded public key used for key wrapping during age encryption. Expected to be RSA 4096. diff --git a/go.mod b/go.mod index 66ec674afc788..4256664e4d387 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( cloud.google.com/go/storage v1.52.0 code.dny.dev/ssrf v0.2.0 connectrpc.com/connect v1.18.1 + filippo.io/age v1.2.1 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 diff --git a/go.sum b/go.sum index f59bf8799457b..de8b76b322ec4 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805 h1:u2qwJeEvnypw+OCPUHmoZE3IqwfuN5kgDfo5MLzpNM0= +c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805/go.mod h1:FomMrUJ2Lxt5jCLmZkG3FHa72zUprnhd3v/Z18Snm4w= cel.dev/expr v0.23.0 h1:wUb94w6OYQS4uXraxo9U+wUAs9jT47Xvl4iPgAwM2ss= cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -643,6 +645,8 @@ cuelang.org/go v0.12.1/go.mod h1:B4+kjvGGQnbkz+GuAv1dq/R308gTkp0sO28FdMrJ2Kw= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/age v1.2.1 h1:X0TZjehAZylOIj4DubWYU1vWQxv9bJpo+Uu2/LGhi1o= +filippo.io/age v1.2.1/go.mod h1:JL9ew2lTN+Pyft4RiNGguFfOpewKwSHm5ayKD/A4004= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= diff --git a/integrations/event-handler/go.mod b/integrations/event-handler/go.mod index f3dbdb776f2db..f74a0fd6bbf2f 100644 --- a/integrations/event-handler/go.mod +++ b/integrations/event-handler/go.mod @@ -34,6 +34,7 @@ require ( cloud.google.com/go/resourcemanager v1.10.6 // indirect connectrpc.com/connect v1.18.1 // indirect dario.cat/mergo v1.0.1 // indirect + filippo.io/age v1.2.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect diff --git a/integrations/event-handler/go.sum b/integrations/event-handler/go.sum index 726bc0b16bbd4..9cb7c6ab0eb25 100644 --- a/integrations/event-handler/go.sum +++ b/integrations/event-handler/go.sum @@ -1,3 +1,5 @@ +c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805 h1:u2qwJeEvnypw+OCPUHmoZE3IqwfuN5kgDfo5MLzpNM0= +c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805/go.mod h1:FomMrUJ2Lxt5jCLmZkG3FHa72zUprnhd3v/Z18Snm4w= cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= cloud.google.com/go/alloydb v1.16.1 h1:pW4D0O2jAfAjoOEI1bgChPwMHWE8X8BjwSO0tfWkWvk= @@ -24,6 +26,8 @@ connectrpc.com/connect v1.18.1 h1:PAg7CjSAGvscaf6YZKUefjoih5Z/qYkyaTrBW8xvYPw= connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +filippo.io/age v1.2.1 h1:X0TZjehAZylOIj4DubWYU1vWQxv9bJpo+Uu2/LGhi1o= +filippo.io/age v1.2.1/go.mod h1:JL9ew2lTN+Pyft4RiNGguFfOpewKwSHm5ayKD/A4004= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= diff --git a/integrations/terraform-mwi/go.mod b/integrations/terraform-mwi/go.mod index b73c1751f8998..8b45aca714147 100644 --- a/integrations/terraform-mwi/go.mod +++ b/integrations/terraform-mwi/go.mod @@ -37,6 +37,7 @@ require ( cloud.google.com/go/storage v1.53.0 // indirect connectrpc.com/connect v1.18.1 // indirect dario.cat/mergo v1.0.1 // indirect + filippo.io/age v1.2.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect diff --git a/integrations/terraform-mwi/go.sum b/integrations/terraform-mwi/go.sum index 59ef4e1b5f3fe..ccd4c7ead7fc3 100644 --- a/integrations/terraform-mwi/go.sum +++ b/integrations/terraform-mwi/go.sum @@ -1,3 +1,5 @@ +c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805 h1:u2qwJeEvnypw+OCPUHmoZE3IqwfuN5kgDfo5MLzpNM0= +c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805/go.mod h1:FomMrUJ2Lxt5jCLmZkG3FHa72zUprnhd3v/Z18Snm4w= cel.dev/expr v0.23.1 h1:K4KOtPCJQjVggkARsjG9RWXP6O4R73aHeJMa/dmCQQg= cel.dev/expr v0.23.1/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -43,6 +45,8 @@ connectrpc.com/connect v1.18.1 h1:PAg7CjSAGvscaf6YZKUefjoih5Z/qYkyaTrBW8xvYPw= connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +filippo.io/age v1.2.1 h1:X0TZjehAZylOIj4DubWYU1vWQxv9bJpo+Uu2/LGhi1o= +filippo.io/age v1.2.1/go.mod h1:JL9ew2lTN+Pyft4RiNGguFfOpewKwSHm5ayKD/A4004= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= diff --git a/integrations/terraform/go.mod b/integrations/terraform/go.mod index 9d631a8ded54a..25b232158e061 100644 --- a/integrations/terraform/go.mod +++ b/integrations/terraform/go.mod @@ -40,6 +40,7 @@ require ( cloud.google.com/go/storage v1.52.0 // indirect connectrpc.com/connect v1.18.1 // indirect dario.cat/mergo v1.0.1 // indirect + filippo.io/age v1.2.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect diff --git a/integrations/terraform/go.sum b/integrations/terraform/go.sum index 2150c681b10b2..77fab17089c27 100644 --- a/integrations/terraform/go.sum +++ b/integrations/terraform/go.sum @@ -1,3 +1,5 @@ +c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805 h1:u2qwJeEvnypw+OCPUHmoZE3IqwfuN5kgDfo5MLzpNM0= +c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805/go.mod h1:FomMrUJ2Lxt5jCLmZkG3FHa72zUprnhd3v/Z18Snm4w= cel.dev/expr v0.23.0 h1:wUb94w6OYQS4uXraxo9U+wUAs9jT47Xvl4iPgAwM2ss= cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -74,6 +76,8 @@ connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2pr dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/age v1.2.1 h1:X0TZjehAZylOIj4DubWYU1vWQxv9bJpo+Uu2/LGhi1o= +filippo.io/age v1.2.1/go.mod h1:JL9ew2lTN+Pyft4RiNGguFfOpewKwSHm5ayKD/A4004= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= diff --git a/integrations/terraform/tfschema/types_terraform.go b/integrations/terraform/tfschema/types_terraform.go index c70892af3dd3f..d1eb9a5ac3561 100644 --- a/integrations/terraform/tfschema/types_terraform.go +++ b/integrations/terraform/tfschema/types_terraform.go @@ -2091,6 +2091,60 @@ func GenSchemaSessionRecordingConfigV2(ctx context.Context) (github_com_hashicor }, "spec": { Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "encryption": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "enabled": { + Description: "Enabled controls whether or not session recordings should be encrypted.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.BoolType, + }, + "manual_key_management": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "active_keys": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.ListNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "label": { + Description: "Label is a value that can be used with the related keystore in order to find relevant keys.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "type": { + Description: "Type represents which keystore should be searched when looking up keys by label.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + }), + Description: "ActiveKeys describe which keys should be queried for active recording encryption and replay.", + Optional: true, + }, + "enabled": { + Description: "Enabled controls whether or recording encryption keys should be managed externally.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.BoolType, + }, + "rotated_keys": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.ListNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{ + "label": { + Description: "Label is a value that can be used with the related keystore in order to find relevant keys.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + "type": { + Description: "Type represents which keystore should be searched when looking up keys by label.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }, + }), + Description: "RotatedKeys describe which keys should be queried for historical replay.", + Optional: true, + }, + }), + Description: "ManualKeyManagement defines whether or not recording encryption keys should be managed externally and how to query those keys.", + Optional: true, + }, + }), + Description: "Encryption configures if and how session recordings should be encrypted.", + Optional: true, + }, "mode": { Computed: true, Description: "Mode controls where (or if) the session is recorded.", @@ -2106,6 +2160,19 @@ func GenSchemaSessionRecordingConfigV2(ctx context.Context) (github_com_hashicor Description: "Spec is a SessionRecordingConfig specification", Optional: true, }, + "status": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.SingleNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{"encryption_keys": { + Attributes: github_com_hashicorp_terraform_plugin_framework_tfsdk.ListNestedAttributes(map[string]github_com_hashicorp_terraform_plugin_framework_tfsdk.Attribute{"public_key": { + Description: "A PKIX ASN.1 DER encoded public key used for key wrapping during age encryption. Expected to be RSA 4096.", + Optional: true, + Type: github_com_hashicorp_terraform_plugin_framework_types.StringType, + }}), + Description: "EncryptionKeys contain the currently active age encryption keys used for encrypted session recording.", + Optional: true, + }}), + Description: "Status is the SessionRecordingConfig status containing active encryption keys", + Optional: true, + }, "sub_kind": { Description: "SubKind is an optional resource sub kind, used in some resources", Optional: true, @@ -22302,6 +22369,266 @@ func CopySessionRecordingConfigV2FromTerraform(_ context.Context, tf github_com_ } CopyFromBoolOption(diags, a, &obj.ProxyChecksHostKeys) } + { + a, ok := tf.Attrs["encryption"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Spec.encryption"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Encryption = nil + if !v.Null && !v.Unknown { + tf := v + obj.Encryption = &github_com_gravitational_teleport_api_types.SessionRecordingEncryptionConfig{} + obj := obj.Encryption + { + a, ok := tf.Attrs["enabled"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Spec.encryption.enabled"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Bool) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.enabled", "github.com/hashicorp/terraform-plugin-framework/types.Bool"}) + } else { + var t bool + if !v.Null && !v.Unknown { + t = bool(v.Value) + } + obj.Enabled = t + } + } + } + { + a, ok := tf.Attrs["manual_key_management"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.ManualKeyManagement = nil + if !v.Null && !v.Unknown { + tf := v + obj.ManualKeyManagement = &github_com_gravitational_teleport_api_types.ManualKeyManagementConfig{} + obj := obj.ManualKeyManagement + { + a, ok := tf.Attrs["enabled"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.enabled"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Bool) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.enabled", "github.com/hashicorp/terraform-plugin-framework/types.Bool"}) + } else { + var t bool + if !v.Null && !v.Unknown { + t = bool(v.Value) + } + obj.Enabled = t + } + } + } + { + a, ok := tf.Attrs["active_keys"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys", "github.com/hashicorp/terraform-plugin-framework/types.List"}) + } else { + obj.ActiveKeys = make([]*github_com_gravitational_teleport_api_types.KeyLabel, len(v.Elems)) + if !v.Null && !v.Unknown { + for k, a := range v.Elems { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys", "github_com_hashicorp_terraform_plugin_framework_types.Object"}) + } else { + var t *github_com_gravitational_teleport_api_types.KeyLabel + if !v.Null && !v.Unknown { + tf := v + t = &github_com_gravitational_teleport_api_types.KeyLabel{} + obj := t + { + a, ok := tf.Attrs["type"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys.type"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys.type", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Type = t + } + } + } + { + a, ok := tf.Attrs["label"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys.label"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys.label", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Label = t + } + } + } + } + obj.ActiveKeys[k] = t + } + } + } + } + } + } + { + a, ok := tf.Attrs["rotated_keys"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys", "github.com/hashicorp/terraform-plugin-framework/types.List"}) + } else { + obj.RotatedKeys = make([]*github_com_gravitational_teleport_api_types.KeyLabel, len(v.Elems)) + if !v.Null && !v.Unknown { + for k, a := range v.Elems { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys", "github_com_hashicorp_terraform_plugin_framework_types.Object"}) + } else { + var t *github_com_gravitational_teleport_api_types.KeyLabel + if !v.Null && !v.Unknown { + tf := v + t = &github_com_gravitational_teleport_api_types.KeyLabel{} + obj := t + { + a, ok := tf.Attrs["type"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys.type"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys.type", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Type = t + } + } + } + { + a, ok := tf.Attrs["label"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys.label"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys.label", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t string + if !v.Null && !v.Unknown { + t = string(v.Value) + } + obj.Label = t + } + } + } + } + obj.RotatedKeys[k] = t + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + { + a, ok := tf.Attrs["status"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Status"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Status", "github.com/hashicorp/terraform-plugin-framework/types.Object"}) + } else { + obj.Status = nil + if !v.Null && !v.Unknown { + tf := v + obj.Status = &github_com_gravitational_teleport_api_types.SessionRecordingConfigStatus{} + obj := obj.Status + { + a, ok := tf.Attrs["encryption_keys"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Status.encryption_keys"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Status.encryption_keys", "github.com/hashicorp/terraform-plugin-framework/types.List"}) + } else { + obj.EncryptionKeys = make([]*github_com_gravitational_teleport_api_types.AgeEncryptionKey, len(v.Elems)) + if !v.Null && !v.Unknown { + for k, a := range v.Elems { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Status.encryption_keys", "github_com_hashicorp_terraform_plugin_framework_types.Object"}) + } else { + var t *github_com_gravitational_teleport_api_types.AgeEncryptionKey + if !v.Null && !v.Unknown { + tf := v + t = &github_com_gravitational_teleport_api_types.AgeEncryptionKey{} + obj := t + { + a, ok := tf.Attrs["public_key"] + if !ok { + diags.Append(attrReadMissingDiag{"SessionRecordingConfigV2.Status.encryption_keys.public_key"}) + } else { + v, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrReadConversionFailureDiag{"SessionRecordingConfigV2.Status.encryption_keys.public_key", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } else { + var t []byte + if !v.Null && !v.Unknown { + t = []byte(v.Value) + } + obj.PublicKey = t + } + } + } + } + obj.EncryptionKeys[k] = t + } + } + } + } + } + } } } } @@ -22611,9 +22938,433 @@ func CopySessionRecordingConfigV2ToTerraform(ctx context.Context, obj *github_co tf.Attrs["proxy_checks_host_keys"] = v } } - } - v.Unknown = false - tf.Attrs["spec"] = v + { + a, ok := tf.AttrTypes["encryption"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Spec.encryption"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["encryption"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Encryption == nil { + v.Null = true + } else { + obj := obj.Encryption + tf := &v + { + t, ok := tf.AttrTypes["enabled"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Spec.encryption.enabled"}) + } else { + v, ok := tf.Attrs["enabled"].(github_com_hashicorp_terraform_plugin_framework_types.Bool) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"SessionRecordingConfigV2.Spec.encryption.enabled", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.Bool) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.enabled", "github.com/hashicorp/terraform-plugin-framework/types.Bool"}) + } + v.Null = bool(obj.Enabled) == false + } + v.Value = bool(obj.Enabled) + v.Unknown = false + tf.Attrs["enabled"] = v + } + } + { + a, ok := tf.AttrTypes["manual_key_management"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["manual_key_management"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.ManualKeyManagement == nil { + v.Null = true + } else { + obj := obj.ManualKeyManagement + tf := &v + { + t, ok := tf.AttrTypes["enabled"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.enabled"}) + } else { + v, ok := tf.Attrs["enabled"].(github_com_hashicorp_terraform_plugin_framework_types.Bool) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.enabled", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.Bool) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.enabled", "github.com/hashicorp/terraform-plugin-framework/types.Bool"}) + } + v.Null = bool(obj.Enabled) == false + } + v.Value = bool(obj.Enabled) + v.Unknown = false + tf.Attrs["enabled"] = v + } + } + { + a, ok := tf.AttrTypes["active_keys"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ListType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys", "github.com/hashicorp/terraform-plugin-framework/types.ListType"}) + } else { + c, ok := tf.Attrs["active_keys"].(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + c = github_com_hashicorp_terraform_plugin_framework_types.List{ + + ElemType: o.ElemType, + Elems: make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.ActiveKeys)), + Null: true, + } + } else { + if c.Elems == nil { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.ActiveKeys)) + } + } + if obj.ActiveKeys != nil { + o := o.ElemType.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if len(obj.ActiveKeys) != len(c.Elems) { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.ActiveKeys)) + } + for k, a := range obj.ActiveKeys { + v, ok := tf.Attrs["active_keys"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if a == nil { + v.Null = true + } else { + obj := a + tf := &v + { + t, ok := tf.AttrTypes["type"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys.type"}) + } else { + v, ok := tf.Attrs["type"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys.type", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys.type", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Type) == "" + } + v.Value = string(obj.Type) + v.Unknown = false + tf.Attrs["type"] = v + } + } + { + t, ok := tf.AttrTypes["label"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys.label"}) + } else { + v, ok := tf.Attrs["label"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys.label", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.active_keys.label", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Label) == "" + } + v.Value = string(obj.Label) + v.Unknown = false + tf.Attrs["label"] = v + } + } + } + v.Unknown = false + c.Elems[k] = v + } + if len(obj.ActiveKeys) > 0 { + c.Null = false + } + } + c.Unknown = false + tf.Attrs["active_keys"] = c + } + } + } + { + a, ok := tf.AttrTypes["rotated_keys"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ListType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys", "github.com/hashicorp/terraform-plugin-framework/types.ListType"}) + } else { + c, ok := tf.Attrs["rotated_keys"].(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + c = github_com_hashicorp_terraform_plugin_framework_types.List{ + + ElemType: o.ElemType, + Elems: make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.RotatedKeys)), + Null: true, + } + } else { + if c.Elems == nil { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.RotatedKeys)) + } + } + if obj.RotatedKeys != nil { + o := o.ElemType.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if len(obj.RotatedKeys) != len(c.Elems) { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.RotatedKeys)) + } + for k, a := range obj.RotatedKeys { + v, ok := tf.Attrs["rotated_keys"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if a == nil { + v.Null = true + } else { + obj := a + tf := &v + { + t, ok := tf.AttrTypes["type"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys.type"}) + } else { + v, ok := tf.Attrs["type"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys.type", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys.type", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Type) == "" + } + v.Value = string(obj.Type) + v.Unknown = false + tf.Attrs["type"] = v + } + } + { + t, ok := tf.AttrTypes["label"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys.label"}) + } else { + v, ok := tf.Attrs["label"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys.label", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Spec.encryption.manual_key_management.rotated_keys.label", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.Label) == "" + } + v.Value = string(obj.Label) + v.Unknown = false + tf.Attrs["label"] = v + } + } + } + v.Unknown = false + c.Elems[k] = v + } + if len(obj.RotatedKeys) > 0 { + c.Null = false + } + } + c.Unknown = false + tf.Attrs["rotated_keys"] = c + } + } + } + } + v.Unknown = false + tf.Attrs["manual_key_management"] = v + } + } + } + } + v.Unknown = false + tf.Attrs["encryption"] = v + } + } + } + } + v.Unknown = false + tf.Attrs["spec"] = v + } + } + } + { + a, ok := tf.AttrTypes["status"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Status"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Status", "github.com/hashicorp/terraform-plugin-framework/types.ObjectType"}) + } else { + v, ok := tf.Attrs["status"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if obj.Status == nil { + v.Null = true + } else { + obj := obj.Status + tf := &v + { + a, ok := tf.AttrTypes["encryption_keys"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Status.encryption_keys"}) + } else { + o, ok := a.(github_com_hashicorp_terraform_plugin_framework_types.ListType) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Status.encryption_keys", "github.com/hashicorp/terraform-plugin-framework/types.ListType"}) + } else { + c, ok := tf.Attrs["encryption_keys"].(github_com_hashicorp_terraform_plugin_framework_types.List) + if !ok { + c = github_com_hashicorp_terraform_plugin_framework_types.List{ + + ElemType: o.ElemType, + Elems: make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.EncryptionKeys)), + Null: true, + } + } else { + if c.Elems == nil { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.EncryptionKeys)) + } + } + if obj.EncryptionKeys != nil { + o := o.ElemType.(github_com_hashicorp_terraform_plugin_framework_types.ObjectType) + if len(obj.EncryptionKeys) != len(c.Elems) { + c.Elems = make([]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(obj.EncryptionKeys)) + } + for k, a := range obj.EncryptionKeys { + v, ok := tf.Attrs["encryption_keys"].(github_com_hashicorp_terraform_plugin_framework_types.Object) + if !ok { + v = github_com_hashicorp_terraform_plugin_framework_types.Object{ + + AttrTypes: o.AttrTypes, + Attrs: make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(o.AttrTypes)), + } + } else { + if v.Attrs == nil { + v.Attrs = make(map[string]github_com_hashicorp_terraform_plugin_framework_attr.Value, len(tf.AttrTypes)) + } + } + if a == nil { + v.Null = true + } else { + obj := a + tf := &v + { + t, ok := tf.AttrTypes["public_key"] + if !ok { + diags.Append(attrWriteMissingDiag{"SessionRecordingConfigV2.Status.encryption_keys.public_key"}) + } else { + v, ok := tf.Attrs["public_key"].(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + i, err := t.ValueFromTerraform(ctx, github_com_hashicorp_terraform_plugin_go_tftypes.NewValue(t.TerraformType(ctx), nil)) + if err != nil { + diags.Append(attrWriteGeneralError{"SessionRecordingConfigV2.Status.encryption_keys.public_key", err}) + } + v, ok = i.(github_com_hashicorp_terraform_plugin_framework_types.String) + if !ok { + diags.Append(attrWriteConversionFailureDiag{"SessionRecordingConfigV2.Status.encryption_keys.public_key", "github.com/hashicorp/terraform-plugin-framework/types.String"}) + } + v.Null = string(obj.PublicKey) == "" + } + v.Value = string(obj.PublicKey) + v.Unknown = false + tf.Attrs["public_key"] = v + } + } + } + v.Unknown = false + c.Elems[k] = v + } + if len(obj.EncryptionKeys) > 0 { + c.Null = false + } + } + c.Unknown = false + tf.Attrs["encryption_keys"] = c + } + } + } + } + v.Unknown = false + tf.Attrs["status"] = v } } } diff --git a/lib/auth/accesspoint/accesspoint.go b/lib/auth/accesspoint/accesspoint.go index bed160811290f..5440a4fe88af1 100644 --- a/lib/auth/accesspoint/accesspoint.go +++ b/lib/auth/accesspoint/accesspoint.go @@ -113,6 +113,7 @@ type Config struct { GitServers services.GitServers HealthCheckConfig services.HealthCheckConfigReader Plugin services.Plugins + RecordingEncryption services.RecordingEncryption } func (c *Config) CheckAndSetDefaults() error { @@ -198,6 +199,7 @@ func NewCache(cfg Config) (*cache.Cache, error) { HealthCheckConfig: cfg.HealthCheckConfig, BotInstanceService: cfg.BotInstance, Plugin: cfg.Plugin, + RecordingEncryption: cfg.RecordingEncryption, } return cache.New(cfg.Setup(cacheCfg)) diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 28cf74e08aa52..4172bd3dbc1fe 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -92,6 +92,7 @@ import ( "github.com/gravitational/teleport/lib/auth/keystore" "github.com/gravitational/teleport/lib/auth/machineid/workloadidentityv1" "github.com/gravitational/teleport/lib/auth/okta" + "github.com/gravitational/teleport/lib/auth/recordingencryption" "github.com/gravitational/teleport/lib/auth/summarizer" "github.com/gravitational/teleport/lib/auth/userloginstate" wanlib "github.com/gravitational/teleport/lib/auth/webauthn" @@ -189,8 +190,15 @@ var ErrRequiresEnterprise = services.ErrRequiresEnterprise type ServerOption func(*Server) error // NewServer creates and configures a new Server instance -func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { - err := metrics.RegisterPrometheusCollectors(prometheusCollectors...) +func NewServer(cfg *InitConfig, opts ...ServerOption) (as *Server, err error) { + closeCtx, cancelFunc := context.WithCancel(context.TODO()) + defer func() { + if err != nil { + cancelFunc() + } + }() + + err = metrics.RegisterPrometheusCollectors(prometheusCollectors...) if err != nil { return nil, trace.Wrap(err) } @@ -226,6 +234,59 @@ func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { } cfg.ClusterConfiguration = clusterConfig } + if cfg.KeyStore == nil { + keystoreOpts := &keystore.Options{ + HostUUID: cfg.HostUUID, + ClusterName: cfg.ClusterName, + AuthPreferenceGetter: cfg.ClusterConfiguration, + FIPS: cfg.FIPS, + } + if cfg.KeyStoreConfig.PKCS11 != (servicecfg.PKCS11Config{}) { + if !modules.GetModules().Features().GetEntitlement(entitlements.HSM).Enabled { + return nil, fmt.Errorf("PKCS11 HSM support requires a license with the HSM feature enabled: %w", ErrRequiresEnterprise) + } + } else if cfg.KeyStoreConfig.GCPKMS != (servicecfg.GCPKMSConfig{}) { + if !modules.GetModules().Features().GetEntitlement(entitlements.HSM).Enabled { + return nil, fmt.Errorf("GCP KMS support requires a license with the HSM feature enabled: %w", ErrRequiresEnterprise) + } + } else if cfg.KeyStoreConfig.AWSKMS != nil { + if !modules.GetModules().Features().GetEntitlement(entitlements.HSM).Enabled { + return nil, fmt.Errorf("AWS KMS support requires a license with the HSM feature enabled: %w", ErrRequiresEnterprise) + } + } + cfg.KeyStore, err = keystore.NewManager(context.Background(), &cfg.KeyStoreConfig, keystoreOpts) + if err != nil { + return nil, trace.Wrap(err) + } + } + if cfg.RecordingEncryption == nil { + localRecordingEncryption, err := local.NewRecordingEncryptionService(cfg.Backend) + if err != nil { + return nil, trace.Wrap(err) + } + + recordingEncryptionManager, err := recordingencryption.NewManager(closeCtx, recordingencryption.ManagerConfig{ + Backend: localRecordingEncryption, + Cache: localRecordingEncryption, + ClusterConfig: cfg.ClusterConfiguration, + KeyStore: cfg.KeyStore, + Logger: cfg.Logger, + InitialSessionRecordingConfig: cfg.SessionRecordingConfig, + LockConfig: backend.RunWhileLockedConfig{ + LockConfiguration: backend.LockConfiguration{ + Backend: cfg.Backend, + TTL: time.Second * 30, + LockNameComponents: []string{"recording_encryption"}, + }, + }, + }) + if err != nil { + return nil, trace.Wrap(err, "initializing session recording encryption") + } + + cfg.RecordingEncryption = recordingEncryptionManager + cfg.ClusterConfiguration = recordingEncryptionManager + } if cfg.AutoUpdateService == nil { cfg.AutoUpdateService, err = local.NewAutoUpdateService(cfg.Backend) if err != nil { @@ -479,30 +540,6 @@ func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { limiter := limiter.NewConnectionsLimiter(defaults.LimiterMaxConcurrentSignatures) - keystoreOpts := &keystore.Options{ - HostUUID: cfg.HostUUID, - ClusterName: cfg.ClusterName, - AuthPreferenceGetter: cfg.ClusterConfiguration, - FIPS: cfg.FIPS, - } - if cfg.KeyStoreConfig.PKCS11 != (servicecfg.PKCS11Config{}) { - if !modules.GetModules().Features().GetEntitlement(entitlements.HSM).Enabled { - return nil, fmt.Errorf("PKCS11 HSM support requires a license with the HSM feature enabled: %w", ErrRequiresEnterprise) - } - } else if cfg.KeyStoreConfig.GCPKMS != (servicecfg.GCPKMSConfig{}) { - if !modules.GetModules().Features().GetEntitlement(entitlements.HSM).Enabled { - return nil, fmt.Errorf("GCP KMS support requires a license with the HSM feature enabled: %w", ErrRequiresEnterprise) - } - } else if cfg.KeyStoreConfig.AWSKMS != nil { - if !modules.GetModules().Features().GetEntitlement(entitlements.HSM).Enabled { - return nil, fmt.Errorf("AWS KMS support requires a license with the HSM feature enabled: %w", ErrRequiresEnterprise) - } - } - keyStore, err := keystore.NewManager(context.Background(), &cfg.KeyStoreConfig, keystoreOpts) - if err != nil { - return nil, trace.Wrap(err) - } - if cfg.KubeWaitingContainers == nil { cfg.KubeWaitingContainers, err = local.NewKubeWaitingContainerService(cfg.Backend) if err != nil { @@ -524,7 +561,6 @@ func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { } } - closeCtx, cancelFunc := context.WithCancel(context.TODO()) services := &Services{ TrustInternal: cfg.Trust, PresenceInternal: cfg.Presence, @@ -582,9 +618,10 @@ func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { VnetConfigService: cfg.VnetConfigService, MultipartHandler: cfg.MultipartHandler, Summarizer: cfg.Summarizer, + RecordingEncryptionManager: cfg.RecordingEncryption, } - as := Server{ + as = &Server{ bk: cfg.Backend, clock: cfg.Clock, limiter: limiter, @@ -598,7 +635,7 @@ func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { Unstable: local.NewUnstableService(cfg.Backend, cfg.AssertionReplayService), Services: services, Cache: services, - keyStore: keyStore, + keyStore: cfg.KeyStore, traceClient: cfg.TraceClient, fips: cfg.FIPS, loadAllCAs: cfg.LoadAllCAs, @@ -607,7 +644,7 @@ func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { logger: cfg.Logger, sessionSummarizerProvider: cfg.SessionSummarizerProvider, } - as.inventory = inventory.NewController(&as, services, + as.inventory = inventory.NewController(as, services, inventory.WithAuthServerID(cfg.HostUUID), inventory.WithClock(cfg.Clock), inventory.WithOnConnect(func(s string) { @@ -627,7 +664,7 @@ func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { ) for _, o := range opts { - if err := o(&as); err != nil { + if err := o(as); err != nil { return nil, trace.Wrap(err) } } @@ -734,9 +771,9 @@ func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { // Add in a login hook for generating state during user login. as.ulsGenerator, err = userloginstate.NewGenerator(userloginstate.GeneratorConfig{ Log: as.logger, - AccessLists: &as, - Access: &as, - UsageEvents: &as, + AccessLists: as, + Access: as, + UsageEvents: as, Clock: cfg.Clock, Emitter: as.emitter, }) @@ -758,7 +795,7 @@ func NewServer(cfg *InitConfig, opts ...ServerOption) (*Server, error) { as.logger.WarnContext(closeCtx, "Auth server starting without cache (may have negative performance implications)") } - return &as, nil + return as, nil } // Services is a collection of services that are used by the auth server. @@ -827,6 +864,7 @@ type Services struct { services.VnetConfigService events.MultipartHandler services.Summarizer + RecordingEncryptionManager } // GetWebSession returns existing web session described by req. diff --git a/lib/auth/auth_test.go b/lib/auth/auth_test.go index 177fbab76a96f..4b1eb960bf5f6 100644 --- a/lib/auth/auth_test.go +++ b/lib/auth/auth_test.go @@ -4019,7 +4019,7 @@ func TestCAGeneration(t *testing.T) { keyStoreManager, err := keystore.NewManager(t.Context(), &servicecfg.KeystoreConfig{}, &keystore.Options{ ClusterName: &types.ClusterNameV2{Metadata: types.Metadata{Name: clusterName}}, AuthPreferenceGetter: &fakeAuthPreferenceGetter{}, - RSAKeyPairSource: func() (priv []byte, pub []byte, err error) { + RSAKeyPairSource: func(alg cryptosuites.Algorithm) (priv []byte, pub []byte, err error) { return privKey, pubKey, nil }, }) diff --git a/lib/auth/authtest/authtest.go b/lib/auth/authtest/authtest.go index 21a0eb66897db..3656ad8e2ae35 100644 --- a/lib/auth/authtest/authtest.go +++ b/lib/auth/authtest/authtest.go @@ -575,6 +575,7 @@ func InitAuthCache(p AuthCacheParams) error { HealthCheckConfig: p.AuthServer.Services.HealthCheckConfig, BotInstance: p.AuthServer.Services.BotInstance, Plugin: p.AuthServer.Services.Plugins, + RecordingEncryption: p.AuthServer.Services.RecordingEncryptionManager, }) if err != nil { return trace.Wrap(err) diff --git a/lib/auth/clusterconfig/clusterconfigv1/service.go b/lib/auth/clusterconfig/clusterconfigv1/service.go index 0baa958a37a2e..017f8130318f7 100644 --- a/lib/auth/clusterconfig/clusterconfigv1/service.go +++ b/lib/auth/clusterconfig/clusterconfigv1/service.go @@ -738,6 +738,10 @@ func (s *Service) CreateSessionRecordingConfig(ctx context.Context, cfg types.Se return nil, trace.AccessDenied("this request can be only executed by an auth server") } + if err := services.ValidateSessionRecordingConfig(cfg, s.signatureAlgorithmSuiteParams.FIPS, s.signatureAlgorithmSuiteParams.Cloud); err != nil { + return nil, trace.Wrap(err) + } + created, err := s.backend.CreateSessionRecordingConfig(ctx, cfg) if err != nil { return nil, trace.Wrap(err) @@ -772,6 +776,10 @@ func (s *Service) UpdateSessionRecordingConfig(ctx context.Context, req *cluster req.SessionRecordingConfig.SetOrigin(types.OriginDynamic) + if err := services.ValidateSessionRecordingConfig(req.SessionRecordingConfig, s.signatureAlgorithmSuiteParams.FIPS, s.signatureAlgorithmSuiteParams.Cloud); err != nil { + return nil, trace.Wrap(err) + } + updated, err := s.backend.UpdateSessionRecordingConfig(ctx, req.SessionRecordingConfig) if err := s.emitter.EmitAuditEvent(ctx, &apievents.SessionRecordingConfigUpdate{ @@ -818,6 +826,10 @@ func (s *Service) UpsertSessionRecordingConfig(ctx context.Context, req *cluster req.SessionRecordingConfig.SetOrigin(types.OriginDynamic) + if err := services.ValidateSessionRecordingConfig(req.SessionRecordingConfig, s.signatureAlgorithmSuiteParams.FIPS, s.signatureAlgorithmSuiteParams.Cloud); err != nil { + return nil, trace.Wrap(err) + } + upserted, err := s.backend.UpsertSessionRecordingConfig(ctx, req.SessionRecordingConfig) if err := s.emitter.EmitAuditEvent(ctx, &apievents.SessionRecordingConfigUpdate{ diff --git a/lib/auth/grpcserver.go b/lib/auth/grpcserver.go index 299b1fb7b0e3b..938620ca9af05 100644 --- a/lib/auth/grpcserver.go +++ b/lib/auth/grpcserver.go @@ -67,6 +67,7 @@ import ( mfav1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/mfa/v1" notificationsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/notifications/v1" presencev1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/presence/v1" + recordingencryptionv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" recordingmetadatav1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingmetadata/v1" secreportsv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/secreports/v1" stableunixusersv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/stableunixusers/v1" @@ -105,6 +106,7 @@ import ( "github.com/gravitational/teleport/lib/auth/machineid/workloadidentityv1" "github.com/gravitational/teleport/lib/auth/notifications/notificationsv1" "github.com/gravitational/teleport/lib/auth/presence/presencev1" + "github.com/gravitational/teleport/lib/auth/recordingencryption/recordingencryptionv1" "github.com/gravitational/teleport/lib/auth/recordingmetadata/recordingmetadatav1" "github.com/gravitational/teleport/lib/auth/secreports/secreportsv1" "github.com/gravitational/teleport/lib/auth/stableunixusers" @@ -5793,6 +5795,17 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) { } userloginstatev1pb.RegisterUserLoginStateServiceServer(server, userLoginStateServer) + recordingEncryptionService, err := recordingencryptionv1.NewService(recordingencryptionv1.ServiceConfig{ + Authorizer: cfg.Authorizer, + Uploader: cfg.AuthServer.Services, + KeyRotater: cfg.AuthServer.Services, + Logger: cfg.AuthServer.logger.With(teleport.ComponentKey, teleport.ComponentRecordingEncryption), + }) + if err != nil { + return nil, trace.Wrap(err) + } + recordingencryptionv1pb.RegisterRecordingEncryptionServiceServer(server, recordingEncryptionService) + clusterConfigService, err := clusterconfigv1.NewService(clusterconfigv1.ServiceConfig{ Cache: cfg.AuthServer.Cache, Backend: cfg.AuthServer.Services, diff --git a/lib/auth/init.go b/lib/auth/init.go index 85815704d9240..e3650e9d015a0 100644 --- a/lib/auth/init.go +++ b/lib/auth/init.go @@ -57,6 +57,8 @@ import ( "github.com/gravitational/teleport/lib/auth/keystore" "github.com/gravitational/teleport/lib/auth/machineid/machineidv1" "github.com/gravitational/teleport/lib/auth/migration" + "github.com/gravitational/teleport/lib/auth/recordingencryption" + "github.com/gravitational/teleport/lib/auth/recordingencryption/recordingencryptionv1" "github.com/gravitational/teleport/lib/auth/state" "github.com/gravitational/teleport/lib/auth/summarizer" "github.com/gravitational/teleport/lib/backend" @@ -86,6 +88,15 @@ type VersionStorage interface { DeleteTeleportVersion(ctx context.Context) error } +// RecordingEncryptionManager wraps a RecordingEncryption backend service with higher level +// operations. +type RecordingEncryptionManager interface { + services.RecordingEncryption + recordingencryption.KeyUnwrapper + recordingencryptionv1.KeyRotater + SetCache(cache recordingencryption.Cache) +} + // InitConfig is auth server init config type InitConfig struct { // Backend is auth backend to use @@ -101,6 +112,10 @@ type InitConfig struct { // keys that may be held in an HSM. KeyStoreConfig servicecfg.KeystoreConfig + // KeyStore handles private CA keys and encryption keys that may be held + // in an HSM. + KeyStore *keystore.Manager + // HostUUID is a UUID of this host HostUUID string @@ -368,6 +383,9 @@ type InitConfig struct { // BackendInfo is a service of backend information. BackendInfo services.BackendInfoService + // RecordingEncryption manages state for encrypted session recording. + RecordingEncryption RecordingEncryptionManager + // SkipVersionCheck skips version check during major version upgrade/downgrade. SkipVersionCheck bool @@ -522,7 +540,14 @@ func initCluster(ctx context.Context, cfg InitConfig, asrv *Server) error { }) g.Go(func() error { - ctx, span := cfg.Tracer.Start(gctx, "auth/InitializeSessionRecordingConfig") + ctx, span := cfg.Tracer.Start(gctx, "auth/initializeAuthPreference") + if err := initializeAuthPreference(ctx, asrv, cfg.AuthPreference); err != nil { + span.End() + return trace.Wrap(err) + } + span.End() + + ctx, span = cfg.Tracer.Start(gctx, "auth/InitializeSessionRecordingConfig") defer span.End() return trace.Wrap(initializeSessionRecordingConfig(ctx, asrv, cfg.SessionRecordingConfig)) }) @@ -539,12 +564,6 @@ func initCluster(ctx context.Context, cfg InitConfig, asrv *Server) error { return trace.Wrap(initializeVnetConfig(ctx, asrv)) }) - g.Go(func() error { - ctx, span := cfg.Tracer.Start(gctx, "auth/initializeAuthPreference") - defer span.End() - return trace.Wrap(initializeAuthPreference(ctx, asrv, cfg.AuthPreference)) - }) - g.Go(func() error { _, span := cfg.Tracer.Start(gctx, "auth/SetStaticTokens") defer span.End() diff --git a/lib/auth/keystore/aws_kms.go b/lib/auth/keystore/aws_kms.go index 6f8e8c01e6b99..a09507abb7681 100644 --- a/lib/auth/keystore/aws_kms.go +++ b/lib/auth/keystore/aws_kms.go @@ -54,8 +54,10 @@ import ( ) const ( - awskmsPrefix = "awskms:" - clusterTagKey = "TeleportCluster" + awskmsPrefix = "awskms:" + clusterTagKey = "TeleportCluster" + encryptedClusterTagKey = "TeleportClusterEncryption" + awsOAEPHash = crypto.SHA256 pendingKeyBaseRetryInterval = time.Second / 2 pendingKeyMaxRetryInterval = 4 * time.Second @@ -130,7 +132,7 @@ func newAWSKMSKeystore(ctx context.Context, cfg *servicecfg.AWSKMSConfig, opts * tags := cfg.Tags if tags == nil { - tags = make(map[string]string, 1) + tags = make(map[string]string, 2) } if _, ok := tags[clusterTagKey]; !ok { tags[clusterTagKey] = opts.ClusterName.GetClusterName() @@ -174,12 +176,19 @@ func (a *awsKMSKeystore) keyTypeDescription() string { return fmt.Sprintf("AWS KMS keys in account %s and region %s", a.awsAccount, a.awsRegion) } -// generateKey creates a new private key and returns its identifier and a crypto.Signer. The returned -// identifier can be passed to getSigner later to get an equivalent crypto.Signer. -func (a *awsKMSKeystore) generateKey(ctx context.Context, algorithm cryptosuites.Algorithm) ([]byte, crypto.Signer, error) { +func (u keyUsage) toAWS() kmstypes.KeyUsageType { + switch u { + case keyUsageDecrypt: + return kmstypes.KeyUsageTypeEncryptDecrypt + default: + return kmstypes.KeyUsageTypeSignVerify + } +} + +func (a *awsKMSKeystore) generateKey(ctx context.Context, algorithm cryptosuites.Algorithm, usage keyUsage) (awsKMSKeyID, error) { alg, err := awsAlgorithm(algorithm) if err != nil { - return nil, nil, trace.Wrap(err) + return awsKMSKeyID{}, trace.Wrap(err) } a.logger.InfoContext(ctx, "Creating new AWS KMS keypair.", @@ -188,6 +197,9 @@ func (a *awsKMSKeystore) generateKey(ctx context.Context, algorithm cryptosuites tags := make([]kmstypes.Tag, 0, len(a.tags)) for k, v := range a.tags { + if k == clusterTagKey && usage == keyUsageDecrypt { + k = encryptedClusterTagKey + } tags = append(tags, kmstypes.Tag{ TagKey: aws.String(k), TagValue: aws.String(v), @@ -197,18 +209,29 @@ func (a *awsKMSKeystore) generateKey(ctx context.Context, algorithm cryptosuites output, err := a.kms.CreateKey(ctx, &kms.CreateKeyInput{ Description: aws.String("Teleport CA key"), KeySpec: alg, - KeyUsage: kmstypes.KeyUsageTypeSignVerify, + KeyUsage: usage.toAWS(), Tags: tags, MultiRegion: aws.Bool(a.multiRegionEnabled), }) if err != nil { - return nil, nil, trace.Wrap(err) + return awsKMSKeyID{}, trace.Wrap(err) } if output.KeyMetadata == nil { - return nil, nil, trace.Errorf("KeyMetadata of generated key is nil") + return awsKMSKeyID{}, trace.Errorf("KeyMetadata of generated key is nil") } keyARN := aws.ToString(output.KeyMetadata.Arn) key, err := keyIDFromArn(keyARN) + if err != nil { + return awsKMSKeyID{}, trace.Wrap(err) + } + + return key, nil +} + +// generateSigner creates a new private key and returns its identifier and a crypto.Signer. The returned +// identifier can be passed to getSigner later to get an equivalent crypto.Signer. +func (a *awsKMSKeystore) generateSigner(ctx context.Context, algorithm cryptosuites.Algorithm) ([]byte, crypto.Signer, error) { + key, err := a.generateKey(ctx, algorithm, keyUsageSign) if err != nil { return nil, nil, trace.Wrap(err) } @@ -216,17 +239,37 @@ func (a *awsKMSKeystore) generateKey(ctx context.Context, algorithm cryptosuites if err != nil { return nil, nil, trace.Wrap(err) } - signer, err := a.newSigner(ctx, key) + signer, err := a.newKMSKey(ctx, key) if err != nil { return nil, nil, trace.Wrap(err) } return keyID, signer, nil } +// generateDecrypter creates a new private key and returns its identifier and a crypto.Decrypter. The returned +// identifier can be passed to getDecrypter later to get an equivalent crypto.Decrypter. +func (a *awsKMSKeystore) generateDecrypter(ctx context.Context, algorithm cryptosuites.Algorithm) ([]byte, crypto.Decrypter, crypto.Hash, error) { + key, err := a.generateKey(ctx, algorithm, keyUsageDecrypt) + if err != nil { + return nil, nil, awsOAEPHash, trace.Wrap(err) + } + keyID, err := a.applyMRKConfig(ctx, key) + if err != nil { + return nil, nil, awsOAEPHash, trace.Wrap(err) + } + decrypter, err := a.newKMSKey(ctx, key) + if err != nil { + return nil, nil, awsOAEPHash, trace.Wrap(err) + } + return keyID, decrypter, awsOAEPHash, nil +} + func awsAlgorithm(alg cryptosuites.Algorithm) (kmstypes.KeySpec, error) { switch alg { case cryptosuites.RSA2048: return kmstypes.KeySpecRsa2048, nil + case cryptosuites.RSA4096: + return kmstypes.KeySpecRsa4096, nil case cryptosuites.ECDSAP256: return kmstypes.KeySpecEccNistP256, nil } @@ -239,16 +282,67 @@ func (a *awsKMSKeystore) getSigner(ctx context.Context, rawKey []byte, publicKey if err != nil { return nil, trace.Wrap(err) } - return a.newSignerWithPublicKey(ctx, key, publicKey) + return a.newKMSKeyWithPublicKey(ctx, key, publicKey) } -type awsKMSSigner struct { +// getDecrypter returns a crypto.Decrypter for the given key identifier, if it is found. +func (a *awsKMSKeystore) getDecrypter(ctx context.Context, rawKey []byte, publicKey crypto.PublicKey, hash crypto.Hash) (crypto.Decrypter, error) { + key, err := parseAWSKMSKeyID(rawKey) + if err != nil { + return nil, trace.Wrap(err) + } + return a.newKMSKeyWithPublicKey(ctx, key, publicKey) +} + +func (a *awsKMSKeystore) findDecryptersByLabel(ctx context.Context, label *types.KeyLabel) ([]crypto.Decrypter, error) { + if label == nil || label.Type != storeAWS { + return nil, nil + } + + describeOut, err := a.kms.DescribeKey(ctx, &kms.DescribeKeyInput{ + KeyId: aws.String(label.Label), + }) + if err != nil { + return nil, trace.Wrap(err) + } + + if describeOut.KeyMetadata.KeyUsage != kmstypes.KeyUsageTypeEncryptDecrypt { + return nil, trace.BadParameter("key usage must be encrypt/decrypt to be used as a decrypter") + } + + if describeOut.KeyMetadata.KeySpec != kmstypes.KeySpecRsa4096 { + return nil, trace.BadParameter("key spec must be RSA 4096 to be used as a decrypter") + } + + pubKeyOut, err := a.kms.GetPublicKey(ctx, &kms.GetPublicKeyInput{ + KeyId: aws.String(label.Label), + }) + if err != nil { + return nil, trace.Wrap(err) + } + + pubKey, err := x509.ParsePKIXPublicKey(pubKeyOut.PublicKey) + if err != nil { + return nil, trace.Wrap(err) + } + + keyID, err := keyIDFromArn(*describeOut.KeyMetadata.Arn) + if err != nil { + return nil, trace.Wrap(err) + } + + decrypter, err := a.newKMSKeyWithPublicKey(ctx, keyID, pubKey) + return []crypto.Decrypter{decrypter}, trace.Wrap(err) + +} + +type awsKMSKey struct { key awsKMSKeyID pub crypto.PublicKey kms kmsClient } -func (a *awsKMSKeystore) newSigner(ctx context.Context, key awsKMSKeyID) (*awsKMSSigner, error) { +func (a *awsKMSKeystore) newKMSKey(ctx context.Context, key awsKMSKeyID) (*awsKMSKey, error) { var pubkeyDER []byte err := a.retryOnConsistencyError(ctx, func(ctx context.Context) error { a.logger.DebugContext(ctx, "Fetching public key", "key_arn", key.arn) @@ -270,7 +364,7 @@ func (a *awsKMSKeystore) newSigner(ctx context.Context, key awsKMSKeyID) (*awsKM if err != nil { return nil, trace.Wrap(err, "unexpected error parsing public key der") } - return a.newSignerWithPublicKey(ctx, key, pub) + return a.newKMSKeyWithPublicKey(ctx, key, pub) } // retryOnConsistencyError handles retrying KMS key operations that may fail @@ -315,8 +409,8 @@ func (a *awsKMSKeystore) retryOnConsistencyError(ctx context.Context, fn func(ct } } -func (a *awsKMSKeystore) newSignerWithPublicKey(_ context.Context, key awsKMSKeyID, publicKey crypto.PublicKey) (*awsKMSSigner, error) { - return &awsKMSSigner{ +func (a *awsKMSKeystore) newKMSKeyWithPublicKey(_ context.Context, key awsKMSKeyID, publicKey crypto.PublicKey) (*awsKMSKey, error) { + return &awsKMSKey{ key: key, pub: publicKey, kms: a.kms, @@ -324,12 +418,12 @@ func (a *awsKMSKeystore) newSignerWithPublicKey(_ context.Context, key awsKMSKey } // Public returns the public key for the signer. -func (a *awsKMSSigner) Public() crypto.PublicKey { +func (a *awsKMSKey) Public() crypto.PublicKey { return a.pub } // Sign signs the message digest. -func (a *awsKMSSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { +func (a *awsKMSKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { var signingAlg kmstypes.SigningAlgorithmSpec switch opts.HashFunc() { case crypto.SHA256: @@ -365,6 +459,27 @@ func (a *awsKMSSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpt return output.Signature, nil } +// Decrypt decrypts data encrypted with the public key +func (a *awsKMSKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) { + var encAlg kmstypes.EncryptionAlgorithmSpec + switch a.pub.(type) { + case *rsa.PublicKey: + encAlg = kmstypes.EncryptionAlgorithmSpecRsaesOaepSha256 + default: + return nil, trace.BadParameter("unsupported key algorithm for AWS KMS decryption") + } + + output, err := a.kms.Decrypt(context.TODO(), &kms.DecryptInput{ + KeyId: aws.String(a.key.id), + CiphertextBlob: ciphertext, + EncryptionAlgorithm: encAlg, + }) + if err != nil { + return nil, trace.Wrap(err) + } + return output.Plaintext, nil +} + // deleteKey deletes the given key from the KeyStore. func (a *awsKMSKeystore) deleteKey(ctx context.Context, rawKey []byte) error { keyID, err := parseAWSKMSKeyID(rawKey) @@ -378,9 +493,9 @@ func (a *awsKMSKeystore) deleteKey(ctx context.Context, rawKey []byte) error { return trace.Wrap(err, "error deleting AWS KMS key") } -// canSignWithKey returns true if this KeyStore is able to sign with the given +// canUseKey returns true if this KeyStore is able to sign with the given // key. -func (a *awsKMSKeystore) canSignWithKey(ctx context.Context, raw []byte, keyType types.PrivateKeyType) (bool, error) { +func (a *awsKMSKeystore) canUseKey(ctx context.Context, raw []byte, keyType types.PrivateKeyType) (bool, error) { if keyType != types.PrivateKeyType_AWS_KMS { return false, nil } @@ -408,7 +523,7 @@ func (a *awsKMSKeystore) canSignWithKey(ctx context.Context, raw []byte, keyType func (a *awsKMSKeystore) deleteUnusedKeys(ctx context.Context, activeKeys [][]byte) error { activeAWSKMSKeys := make(map[string]int) for _, activeKey := range activeKeys { - keyIsRelevent, err := a.canSignWithKey(ctx, activeKey, keyType(activeKey)) + keyIsRelevent, err := a.canUseKey(ctx, activeKey, keyType(activeKey)) if err != nil { // Don't expect this error to ever hit, safer to return if it does. return trace.Wrap(err) @@ -434,7 +549,14 @@ func (a *awsKMSKeystore) deleteUnusedKeys(ctx context.Context, activeKeys [][]by if scopedKeyDeletion { keyListFn = a.forEachOwnedKey } - err := keyListFn(ctx, func(ctx context.Context, arn string) error { + err := keyListFn(ctx, func(ctx context.Context, arn string, tags []rgttypes.Tag) error { + if slices.ContainsFunc(tags, func(tag rgttypes.Tag) bool { + return aws.ToString(tag.Key) == encryptedClusterTagKey + }) { + // do nothing for keys marked with delete prevention + return nil + } + key, err := keyIDFromArn(arn) if err != nil { return trace.Wrap(err) @@ -534,7 +656,7 @@ func (a *awsKMSKeystore) deleteUnusedKeys(ctx context.Context, activeKeys [][]by // forEachKey calls fn with the AWS key ID of all keys in the AWS account and // region that would be returned by ListKeys. It may call fn concurrently. -func (a *awsKMSKeystore) forEachKey(ctx context.Context, fn func(ctx context.Context, keyARN string) error) error { +func (a *awsKMSKeystore) forEachKey(ctx context.Context, fn func(ctx context.Context, keyARN string, tags []rgttypes.Tag) error) error { errGroup, ctx := errgroup.WithContext(ctx) marker := "" more := true @@ -555,7 +677,7 @@ func (a *awsKMSKeystore) forEachKey(ctx context.Context, fn func(ctx context.Con for _, keyEntry := range output.Keys { keyID := aws.ToString(keyEntry.KeyArn) errGroup.Go(func() error { - return trace.Wrap(fn(ctx, keyID)) + return trace.Wrap(fn(ctx, keyID, nil)) }) } } @@ -564,7 +686,7 @@ func (a *awsKMSKeystore) forEachKey(ctx context.Context, fn func(ctx context.Con // forEachOwnedKey calls fn with the AWS key ID of all owned keys in the AWS account and // region that would be returned by GetResources. It may call fn concurrently. -func (a *awsKMSKeystore) forEachOwnedKey(ctx context.Context, fn func(ctx context.Context, keyARN string) error) error { +func (a *awsKMSKeystore) forEachOwnedKey(ctx context.Context, fn func(ctx context.Context, keyARN string, tags []rgttypes.Tag) error) error { const maxGoRoutines = 5 errGroup, ctx := errgroup.WithContext(ctx) errGroup.SetLimit(maxGoRoutines) @@ -594,7 +716,7 @@ func (a *awsKMSKeystore) forEachOwnedKey(ctx context.Context, fn func(ctx contex for _, keyEntry := range output.ResourceTagMappingList { keyID := aws.ToString(keyEntry.ResourceARN) errGroup.Go(func() error { - return trace.Wrap(fn(ctx, keyID)) + return trace.Wrap(fn(ctx, keyID, keyEntry.Tags)) }) } } @@ -799,6 +921,7 @@ type kmsClient interface { DescribeKey(context.Context, *kms.DescribeKeyInput, ...func(*kms.Options)) (*kms.DescribeKeyOutput, error) ListResourceTags(context.Context, *kms.ListResourceTagsInput, ...func(*kms.Options)) (*kms.ListResourceTagsOutput, error) Sign(context.Context, *kms.SignInput, ...func(*kms.Options)) (*kms.SignOutput, error) + Decrypt(context.Context, *kms.DecryptInput, ...func(*kms.Options)) (*kms.DecryptOutput, error) } // mrkClient is a client for managing multi-region keys. diff --git a/lib/auth/keystore/aws_kms_test.go b/lib/auth/keystore/aws_kms_test.go index 1ec4f9d1a0ed0..7886d7ade84e2 100644 --- a/lib/auth/keystore/aws_kms_test.go +++ b/lib/auth/keystore/aws_kms_test.go @@ -20,6 +20,7 @@ import ( "context" "crypto" "crypto/rand" + "crypto/rsa" "crypto/x509" "fmt" "slices" @@ -428,6 +429,7 @@ func newFakeAWSKMSService(t *testing.T, clock clockwork.Clock, account string, r type fakeAWSKMSKey struct { arn arn.ARN privKeyPEM []byte + keyUsage kmstypes.KeyUsageType tags []kmstypes.Tag creationDate time.Time state kmstypes.KeyState @@ -484,6 +486,8 @@ func (f *fakeAWSKMSService) CreateKey(_ context.Context, input *kms.CreateKeyInp switch input.KeySpec { case kmstypes.KeySpecRsa2048: privKeyPEM = testRSA2048PrivateKeyPEM + case kmstypes.KeySpecRsa4096: + privKeyPEM = testRSA4096PrivateKeyPEM case kmstypes.KeySpecEccNistP256: signer, err := cryptosuites.GenerateKeyWithAlgorithm(cryptosuites.ECDSAP256) if err != nil { @@ -499,6 +503,7 @@ func (f *fakeAWSKMSService) CreateKey(_ context.Context, input *kms.CreateKeyInp f.keys = append(f.keys, &fakeAWSKMSKey{ arn: a, privKeyPEM: privKeyPEM, + keyUsage: input.KeyUsage, tags: input.Tags, creationDate: f.clock.Now(), region: f.region, @@ -541,6 +546,9 @@ func (f *fakeAWSKMSService) Sign(_ context.Context, input *kms.SignInput, _ ...f if key.state != kmstypes.KeyStateEnabled { return nil, trace.NotFound("key %q is not enabled", aws.ToString(input.KeyId)) } + if key.keyUsage != kmstypes.KeyUsageTypeSignVerify { + return nil, trace.BadParameter("key %q is not a signing key", aws.ToString(input.KeyId)) + } signer, err := keys.ParsePrivateKey(key.privKeyPEM) if err != nil { return nil, trace.Wrap(err) @@ -563,6 +571,39 @@ func (f *fakeAWSKMSService) Sign(_ context.Context, input *kms.SignInput, _ ...f }, nil } +func (f *fakeAWSKMSService) Decrypt(_ context.Context, input *kms.DecryptInput, _ ...func(*kms.Options)) (*kms.DecryptOutput, error) { + key, err := f.findKey(aws.ToString(input.KeyId)) + if err != nil { + return nil, trace.Wrap(err) + } + if key.state != kmstypes.KeyStateEnabled { + return nil, trace.NotFound("key %q is not enabled", aws.ToString(input.KeyId)) + } + if key.keyUsage != kmstypes.KeyUsageTypeEncryptDecrypt { + return nil, trace.BadParameter("key %q is not a decryption key", aws.ToString(input.KeyId)) + } + signer, err := keys.ParsePrivateKey(key.privKeyPEM) + if err != nil { + return nil, trace.Wrap(err) + } + decrypter, ok := signer.Signer.(crypto.Decrypter) + if !ok { + return nil, trace.Errorf("private key is not a decrypter") + } + switch input.EncryptionAlgorithm { + case kmstypes.EncryptionAlgorithmSpecRsaesOaepSha256: + default: + return nil, trace.BadParameter("unsupported EncryptionAlgorithm %q", input.EncryptionAlgorithm) + } + plaintext, err := decrypter.Decrypt(rand.Reader, input.CiphertextBlob, &rsa.OAEPOptions{Hash: crypto.SHA256}) + if err != nil { + return nil, trace.Wrap(err) + } + return &kms.DecryptOutput{ + Plaintext: plaintext, + }, nil +} + func (f *fakeAWSKMSService) ScheduleKeyDeletion(_ context.Context, input *kms.ScheduleKeyDeletionInput, _ ...func(*kms.Options)) (*kms.ScheduleKeyDeletionOutput, error) { key, err := f.findKey(aws.ToString(input.KeyId)) if err != nil { diff --git a/lib/auth/keystore/gcp_kms.go b/lib/auth/keystore/gcp_kms.go index 917487f5fa1da..0cd36d1aebf51 100644 --- a/lib/auth/keystore/gcp_kms.go +++ b/lib/auth/keystore/gcp_kms.go @@ -45,7 +45,9 @@ import ( const ( // GCP does not allow "." or "/" in labels hostLabel = "teleport_auth_host" + encryptedHostLabel = "teleport_encryption_auth_host" gcpkmsPrefix = "gcpkms:" + gcpOAEPHash = crypto.SHA256 defaultGCPRequestTimeout = 30 * time.Second defaultGCPPendingTimeout = 2 * time.Minute defaultGCPPendingRetryInterval = 5 * time.Second @@ -110,25 +112,27 @@ func (g *gcpKMSKeyStore) keyTypeDescription() string { return fmt.Sprintf("GCP KMS keys in keyring %s", g.keyRing) } -// generateKey creates a new private key and returns its identifier and a crypto.Signer. The returned -// identifier for gcpKMSKeyStore encodes the full GCP KMS key version name, and can be passed to getSigner -// later to get an equivalent crypto.Signer. -func (g *gcpKMSKeyStore) generateKey(ctx context.Context, algorithm cryptosuites.Algorithm) ([]byte, crypto.Signer, error) { - alg, err := gcpAlgorithm(algorithm) +func (g *gcpKMSKeyStore) generateKey(ctx context.Context, algorithm cryptosuites.Algorithm, usage keyUsage) (gcpKMSKeyID, error) { + alg, err := gcpAlgorithm(usage, algorithm) if err != nil { - return nil, nil, trace.Wrap(err) + return gcpKMSKeyID{}, trace.Wrap(err) } keyUUID := uuid.NewString() g.log.InfoContext(ctx, "Creating new GCP KMS keypair.", "id", keyUUID, "algorithm", alg.String()) + label := hostLabel + if usage == keyUsageDecrypt { + label = encryptedHostLabel + } + req := &kmspb.CreateCryptoKeyRequest{ Parent: g.keyRing, CryptoKeyId: keyUUID, CryptoKey: &kmspb.CryptoKey{ - Purpose: kmspb.CryptoKey_ASYMMETRIC_SIGN, + Purpose: usage.toGCP(), Labels: map[string]string{ - hostLabel: g.hostUUID, + label: g.hostUUID, }, VersionTemplate: &kmspb.CryptoKeyVersionTemplate{ ProtectionLevel: g.protectionLevel, @@ -138,40 +142,115 @@ func (g *gcpKMSKeyStore) generateKey(ctx context.Context, algorithm cryptosuites } resp, err := doGCPRequest(ctx, g, g.kmsClient.CreateCryptoKey, req) if err != nil { - return nil, nil, trace.Wrap(err, "error while attempting to generate new GCP KMS key") + return gcpKMSKeyID{}, trace.Wrap(err, "error while attempting to generate new GCP KMS key") } - keyID := gcpKMSKeyID{ + return gcpKMSKeyID{ keyVersionName: resp.Name + keyVersionSuffix, + }, nil +} + +// generateSigner creates a new private key and returns its identifier and a crypto.Signer. The returned +// identifier for gcpKMSKeyStore encodes the full GCP KMS key version name, and can be passed to getSigner +// later to get an equivalent crypto.Signer. +func (g *gcpKMSKeyStore) generateSigner(ctx context.Context, algorithm cryptosuites.Algorithm) ([]byte, crypto.Signer, error) { + keyID, err := g.generateKey(ctx, algorithm, keyUsageSign) + if err != nil { + return nil, nil, trace.Wrap(err) } - signer, err := g.newKmsSigner(ctx, keyID) + signer, err := g.newKmsKey(ctx, keyID) if err != nil { return nil, nil, trace.Wrap(err) } return keyID.marshal(), signer, nil } -func gcpAlgorithm(alg cryptosuites.Algorithm) (kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm, error) { +// generateDecrypter creates a new private key and returns its identifier and a crypto.Decrypter. The returned +// identifier for gcpKMSKeyStore encodes the full GCP KMS key version name, and can be passed to getDecrypter +// later to get an equivalent crypto.Decrypter. +func (g *gcpKMSKeyStore) generateDecrypter(ctx context.Context, algorithm cryptosuites.Algorithm) ([]byte, crypto.Decrypter, crypto.Hash, error) { + keyID, err := g.generateKey(ctx, algorithm, keyUsageDecrypt) + if err != nil { + return nil, nil, gcpOAEPHash, trace.Wrap(err) + } + + decrypter, err := g.newKmsKey(ctx, keyID) + if err != nil { + return nil, nil, gcpOAEPHash, trace.Wrap(err) + } + return keyID.marshal(), decrypter, gcpOAEPHash, nil +} + +func gcpAlgorithm(usage keyUsage, alg cryptosuites.Algorithm) (kmspb.CryptoKeyVersion_CryptoKeyVersionAlgorithm, error) { switch alg { case cryptosuites.RSA2048: - return kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_2048_SHA256, nil + switch usage { + case keyUsageSign: + return kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_2048_SHA256, nil + case keyUsageDecrypt: + return kmspb.CryptoKeyVersion_RSA_DECRYPT_OAEP_2048_SHA256, nil + } + case cryptosuites.RSA4096: + switch usage { + case keyUsageSign: + return kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_4096_SHA256, nil + case keyUsageDecrypt: + return kmspb.CryptoKeyVersion_RSA_DECRYPT_OAEP_4096_SHA256, nil + } case cryptosuites.ECDSAP256: - return kmspb.CryptoKeyVersion_EC_SIGN_P256_SHA256, nil + switch usage { + case keyUsageSign: + return kmspb.CryptoKeyVersion_EC_SIGN_P256_SHA256, nil + case keyUsageDecrypt: + return kmspb.CryptoKeyVersion_CRYPTO_KEY_VERSION_ALGORITHM_UNSPECIFIED, trace.BadParameter("unsupported algorithm for decryption: %v", alg) + } } return kmspb.CryptoKeyVersion_CRYPTO_KEY_VERSION_ALGORITHM_UNSPECIFIED, trace.BadParameter("unsupported algorithm: %v", alg) } -// getSigner returns a crypto.Signer for the given pem-encoded private key. +// getSigner returns a crypto.Signer for the given raw private key. func (g *gcpKMSKeyStore) getSigner(ctx context.Context, rawKey []byte, publicKey crypto.PublicKey) (crypto.Signer, error) { keyID, err := parseGCPKMSKeyID(rawKey) if err != nil { return nil, trace.Wrap(err) } - signer, err := g.newKmsSignerWithPublicKey(ctx, keyID, publicKey) + signer, err := g.newKmsKeyWithPublicKey(ctx, keyID, publicKey) return signer, trace.Wrap(err) } +// getDecrypter returns a crypto.Decrypter for the given raw private key. +func (g *gcpKMSKeyStore) getDecrypter(ctx context.Context, rawKey []byte, publicKey crypto.PublicKey, hash crypto.Hash) (crypto.Decrypter, error) { + keyID, err := parseGCPKMSKeyID(rawKey) + if err != nil { + return nil, trace.Wrap(err) + } + signer, err := g.newKmsKeyWithPublicKey(ctx, keyID, publicKey) + return signer, trace.Wrap(err) +} + +func (g *gcpKMSKeyStore) findDecryptersByLabel(ctx context.Context, label *types.KeyLabel) ([]crypto.Decrypter, error) { + if label == nil || label.Type != storeGCP { + return nil, nil + } + + keyMeta, err := g.kmsClient.GetCryptoKeyVersion(ctx, &kmspb.GetCryptoKeyVersionRequest{ + Name: label.Label, + }) + if err != nil { + return nil, trace.Wrap(err) + } + + switch keyMeta.GetAlgorithm() { + case kmspb.CryptoKeyVersion_RSA_DECRYPT_OAEP_4096_SHA256: + default: + return nil, trace.BadParameter("key spec must be RSA 4096 to be used as a decrypter") + } + + key, err := g.newKmsKey(ctx, gcpKMSKeyID{keyMeta.GetName()}) + return []crypto.Decrypter{key}, trace.Wrap(err) +} + // deleteKey deletes the given key from the KeyStore. func (g *gcpKMSKeyStore) deleteKey(ctx context.Context, rawKey []byte) error { keyID, err := parseGCPKMSKeyID(rawKey) @@ -186,13 +265,13 @@ func (g *gcpKMSKeyStore) deleteKey(ctx context.Context, rawKey []byte) error { return trace.Wrap(err, "error while attempting to delete GCP KMS key") } -// canSignWithKey returns true if given a GCP_KMS key in the same key ring -// managed by this keystore. This means that it's possible (and expected) for +// canUseKey returns true if given a GCP_KMS key in the same key ring managed +// by this keystore. This means that it's possible (and expected) for // multiple auth servers in a cluster to sign with the same KMS keys if they are // configured with the same keyring. This is a divergence from the PKCS#11 // keystore where different auth servers will always create their own keys even // if configured to use the same HSM -func (g *gcpKMSKeyStore) canSignWithKey(ctx context.Context, raw []byte, keyType types.PrivateKeyType) (bool, error) { +func (g *gcpKMSKeyStore) canUseKey(ctx context.Context, raw []byte, keyType types.PrivateKeyType) (bool, error) { if keyType != types.PrivateKeyType_GCP_KMS { return false, nil } @@ -203,6 +282,7 @@ func (g *gcpKMSKeyStore) canSignWithKey(ctx context.Context, raw []byte, keyType if !strings.HasPrefix(keyID.keyVersionName, g.keyRing) { return false, nil } + return true, nil } @@ -228,7 +308,7 @@ func (g *gcpKMSKeyStore) deleteUnusedKeys(ctx context.Context, activeKeys [][]by // check which keys in KMS are unused. activeKmsKeyVersions := make(map[string]int) for _, activeKey := range activeKeys { - keyIsRelevant, err := g.canSignWithKey(ctx, activeKey, keyType(activeKey)) + keyIsRelevant, err := g.canUseKey(ctx, activeKey, keyType(activeKey)) if err != nil { // Don't expect this error to ever hit, safer to return if it does. return trace.Wrap(err) @@ -240,7 +320,7 @@ func (g *gcpKMSKeyStore) deleteUnusedKeys(ctx context.Context, activeKeys [][]by } keyID, err := parseGCPKMSKeyID(activeKey) if err != nil { - // Realistically we should not hit this since canSignWithKey already + // Realistically we should not hit this since canUseKey already // calls parseGCPKMSKeyID. return trace.Wrap(err) } @@ -304,15 +384,15 @@ func (g *gcpKMSKeyStore) deleteUnusedKeys(ctx context.Context, activeKeys [][]by return nil } -// kmsSigner implements the crypto.Signer interface -type kmsSigner struct { +// kmsKey implements the crypto.Signer and crypto.Decrypter interface +type kmsKey struct { ctx context.Context g *gcpKMSKeyStore keyID gcpKMSKeyID public crypto.PublicKey } -func (g *gcpKMSKeyStore) newKmsSigner(ctx context.Context, keyID gcpKMSKeyID) (*kmsSigner, error) { +func (g *gcpKMSKeyStore) newKmsKey(ctx context.Context, keyID gcpKMSKeyID) (*kmsKey, error) { req := &kmspb.GetPublicKeyRequest{ Name: keyID.keyVersionName, } @@ -331,11 +411,11 @@ func (g *gcpKMSKeyStore) newKmsSigner(ctx context.Context, keyID gcpKMSKeyID) (* return nil, trace.Wrap(err, "unexpected error parsing public key PEM") } - return g.newKmsSignerWithPublicKey(ctx, keyID, pub) + return g.newKmsKeyWithPublicKey(ctx, keyID, pub) } -func (g *gcpKMSKeyStore) newKmsSignerWithPublicKey(ctx context.Context, keyID gcpKMSKeyID, publicKey crypto.PublicKey) (*kmsSigner, error) { - return &kmsSigner{ +func (g *gcpKMSKeyStore) newKmsKeyWithPublicKey(ctx context.Context, keyID gcpKMSKeyID, publicKey crypto.PublicKey) (*kmsKey, error) { + return &kmsKey{ ctx: ctx, g: g, keyID: keyID, @@ -343,11 +423,11 @@ func (g *gcpKMSKeyStore) newKmsSignerWithPublicKey(ctx context.Context, keyID gc }, nil } -func (s *kmsSigner) Public() crypto.PublicKey { +func (s *kmsKey) Public() crypto.PublicKey { return s.public } -func (s *kmsSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { +func (s *kmsKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { var ( requestDigest *kmspb.Digest data []byte @@ -383,6 +463,26 @@ func (s *kmsSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) return resp.Signature, nil } +func (s *kmsKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) { + resp, err := doGCPRequest(s.ctx, s.g, s.g.kmsClient.AsymmetricDecrypt, &kmspb.AsymmetricDecryptRequest{ + Name: s.keyID.keyVersionName, + Ciphertext: ciphertext, + }) + if err != nil { + return nil, trace.Wrap(err, "error while attempting GCP KMS decryption operation") + } + return resp.Plaintext, nil +} + +func (u keyUsage) toGCP() kmspb.CryptoKey_CryptoKeyPurpose { + switch u { + case keyUsageDecrypt: + return kmspb.CryptoKey_ASYMMETRIC_DECRYPT + default: + return kmspb.CryptoKey_ASYMMETRIC_SIGN + } +} + type gcpKMSKeyID struct { keyVersionName string } diff --git a/lib/auth/keystore/gcp_kms_test.go b/lib/auth/keystore/gcp_kms_test.go index 922d8b4e3d051..4c05a58c6a37e 100644 --- a/lib/auth/keystore/gcp_kms_test.go +++ b/lib/auth/keystore/gcp_kms_test.go @@ -21,6 +21,7 @@ package keystore import ( "context" "crypto" + "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "encoding/pem" @@ -111,6 +112,8 @@ func (f *fakeGCPKMSServer) CreateCryptoKey(ctx context.Context, req *kmspb.Creat switch cryptoKey.VersionTemplate.Algorithm { case kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_2048_SHA256, kmspb.CryptoKeyVersion_RSA_SIGN_PKCS1_4096_SHA512: pem = testRSA2048PrivateKeyPEM + case kmspb.CryptoKeyVersion_RSA_DECRYPT_OAEP_4096_SHA256: + pem = testRSA4096PrivateKeyPEM case kmspb.CryptoKeyVersion_EC_SIGN_P256_SHA256: signer, err := cryptosuites.GenerateKeyWithAlgorithm(cryptosuites.ECDSAP256) if err != nil { @@ -219,6 +222,40 @@ func (f *fakeGCPKMSServer) AsymmetricSign(ctx context.Context, req *kmspb.Asymme return resp, nil } +func (f *fakeGCPKMSServer) AsymmetricDecrypt(ctx context.Context, req *kmspb.AsymmetricDecryptRequest) (*kmspb.AsymmetricDecryptResponse, error) { + f.mu.RLock() + defer f.mu.RUnlock() + keyState, ok := f.keyVersions[req.Name] + if !ok { + return nil, trace.NotFound("no such key") + } + if keyState.cryptoKeyVersion.State != kmspb.CryptoKeyVersion_ENABLED { + return nil, trace.BadParameter("cannot fetch key, state has value %s", keyState.cryptoKeyVersion.State) + } + + signer, err := keys.ParsePrivateKey(keyState.pem) + if err != nil { + return nil, trace.Wrap(err) + } + + decrypter, ok := signer.Signer.(crypto.Decrypter) + if !ok { + return nil, trace.Errorf("private key is not a valid decrypter") + } + + testRand := mathrandv1.New(mathrandv1.NewSource(0)) + plaintext, err := decrypter.Decrypt(testRand, req.Ciphertext, &rsa.OAEPOptions{Hash: crypto.SHA256}) + if err != nil { + return nil, trace.Wrap(err) + } + + resp := &kmspb.AsymmetricDecryptResponse{ + Plaintext: plaintext, + } + + return resp, nil +} + func (f *fakeGCPKMSServer) ListCryptoKeys(ctx context.Context, req *kmspb.ListCryptoKeysRequest) (*kmspb.ListCryptoKeysResponse, error) { f.mu.RLock() defer f.mu.RUnlock() diff --git a/lib/auth/keystore/keystore_test.go b/lib/auth/keystore/keystore_test.go index 92a09be63c47a..3c9bd5892592b 100644 --- a/lib/auth/keystore/keystore_test.go +++ b/lib/auth/keystore/keystore_test.go @@ -26,6 +26,7 @@ import ( "crypto/rand" "crypto/rsa" "crypto/sha256" + "crypto/x509" "errors" "fmt" "os" @@ -186,7 +187,7 @@ func TestBackends(t *testing.T) { } { t.Run(tc.alg.String(), func(t *testing.T) { // create a key - key, signer, err := backend.generateKey(ctx, tc.alg) + key, signer, err := backend.generateSigner(ctx, tc.alg) require.NoError(t, err, trace.DebugReport(err)) require.Equal(t, backendDesc.expectedKeyType, keyType(key)) @@ -217,18 +218,22 @@ func TestBackends(t *testing.T) { for i := 0; i < numKeys; i++ { var signer crypto.Signer var err error - rawPrivateKeys[i], signer, err = backend.generateKey(ctx, cryptosuites.ECDSAP256) + rawPrivateKeys[i], signer, err = backend.generateSigner(ctx, cryptosuites.ECDSAP256) require.NoError(t, err) publicKeys[i] = signer.Public() } + // generate an encryption key that should not be cleaned up + encryptionKey, decrypter, hash, err := backend.generateDecrypter(ctx, cryptosuites.RSA4096) + require.NoError(t, err) + // AWS KMS keystore will not delete any keys created in the past 5 // minutes. pack.clock.Advance(6 * time.Minute) // say that only the first key is in use, delete the rest usedKeys := [][]byte{rawPrivateKeys[0]} - err := backend.deleteUnusedKeys(ctx, usedKeys) + err = backend.deleteUnusedKeys(ctx, usedKeys) require.NoError(t, err, trace.DebugReport(err)) // make sure the first key is still good @@ -237,6 +242,23 @@ func TestBackends(t *testing.T) { _, err = signer.Sign(rand.Reader, messageHash[:], crypto.SHA256) require.NoError(t, err) + // make sure the encryption key is still good + plaintext := "test message" + pubKey, ok := decrypter.Public().(*rsa.PublicKey) + require.True(t, ok, "expected *rsa.PublicKey, got %T", decrypter.Public()) + + cipher, err := rsa.EncryptOAEP(hash.New(), rand.Reader, pubKey, []byte(plaintext), nil) + require.NoError(t, err) + + decrypter, err = backend.getDecrypter(ctx, encryptionKey, decrypter.Public(), hash) + require.NoError(t, err) + + decrypted, err := decrypter.Decrypt(rand.Reader, cipher, &rsa.OAEPOptions{ + Hash: hash, + }) + require.NoError(t, err) + require.Equal(t, plaintext, string(decrypted)) + // make sure all other keys are deleted for i := 1; i < numKeys; i++ { signer, err := backend.getSigner(ctx, rawPrivateKeys[i], publicKeys[0]) @@ -304,6 +326,10 @@ func TestManager(t *testing.T) { require.NoError(t, err) require.Equal(t, backendDesc.expectedKeyType, jwtKeyPair.PrivateKeyType) + encKeyPair, err := manager.NewEncryptionKeyPair(ctx, cryptosuites.RecordingKeyWrapping) + require.NoError(t, err) + require.Equal(t, backendDesc.expectedKeyType, encKeyPair.PrivateKeyType) + // Test a CA with multiple active keypairs. Each element of ActiveKeys // includes a keypair generated above and a PKCS11 keypair with a // different hostID that this manager should not be able to use. @@ -328,7 +354,7 @@ func TestManager(t *testing.T) { require.NoError(t, err) // Test that the manager is able to select the correct key and get a - // signer. + // signer or decrypter. sshSigner, err := manager.GetSSHSigner(ctx, ca) require.NoError(t, err, trace.DebugReport(err)) require.Equal(t, sshKeyPair.PublicKey, ssh.MarshalAuthorizedKey(sshSigner.PublicKey())) @@ -344,6 +370,25 @@ func TestManager(t *testing.T) { require.NoError(t, err) require.Equal(t, jwtKeyPair.PublicKey, pubkeyPem) + decrypter, err := manager.GetDecrypter(ctx, encKeyPair) + require.NoError(t, err) + require.NotNil(t, decrypter) + + // Try encrypting and decrypting some data + msg := []byte("teleport") + require.NoError(t, err) + pubKey, err := x509.ParsePKIXPublicKey(encKeyPair.PublicKey) + require.NoError(t, err) + pubKeyRSA, ok := pubKey.(*rsa.PublicKey) + require.True(t, ok, "expected RSA public key") + + ciphertext, err := rsa.EncryptOAEP(crypto.Hash(encKeyPair.Hash).New(), rand.Reader, pubKeyRSA, msg, nil) + require.NoError(t, err) + + plaintext, err := decrypter.Decrypt(rand.Reader, ciphertext, nil) + require.NoError(t, err) + require.Equal(t, msg, plaintext) + // Try signing an SSH cert. sshCert := ssh.Certificate{ Key: sshSubjectPubKey, @@ -560,9 +605,21 @@ func newTestPack(ctx context.Context, t *testing.T) *testPack { }, kmsClient: testGCPKMSClient, clockworkOverride: clock, + RSAKeyPairSource: func(alg cryptosuites.Algorithm) ([]byte, []byte, error) { + switch alg { + case cryptosuites.RSA2048: + return testRSA2048PrivateKeyPEM, nil, nil + case cryptosuites.RSA4096: + return testRSA4096PrivateKeyPEM, nil, nil + } + + return nil, nil, trace.Errorf("unexpected algorithm: %v", alg) + }, } - softwareBackend := newSoftwareKeyStore(&softwareConfig{}) + softwareBackend := newSoftwareKeyStore(&softwareConfig{ + rsaKeyPairSource: baseOpts.RSAKeyPairSource, + }) backends = append(backends, &backendDesc{ name: "software", config: servicecfg.KeystoreConfig{}, @@ -573,12 +630,15 @@ func newTestPack(ctx context.Context, t *testing.T) *testPack { }) if config, ok := softHSMTestConfig(t); ok { - backend, err := newPKCS11KeyStore(&config.PKCS11, &baseOpts) + hsmOpts := baseOpts + // softhsm2 seems to only support OAEP with SHA1 + hsmOpts.OAEPHash = crypto.SHA1 + backend, err := newPKCS11KeyStore(&config.PKCS11, &hsmOpts) require.NoError(t, err) backends = append(backends, &backendDesc{ name: "softhsm", config: config, - opts: &baseOpts, + opts: &hsmOpts, backend: backend, expectedKeyType: types.PrivateKeyType_PKCS11, unusedRawKey: unusedPKCS11Key, diff --git a/lib/auth/keystore/manager.go b/lib/auth/keystore/manager.go index a89f0cfae929d..9d9c8a6deb6d6 100644 --- a/lib/auth/keystore/manager.go +++ b/lib/auth/keystore/manager.go @@ -58,10 +58,11 @@ import ( const ( keystoreSubsystem = "keystore" - labelKeyType = "key_type" - keyTypeTLS = "tls" - keyTypeSSH = "ssh" - keyTypeJWT = "jwt" + labelKeyType = "key_type" + keyTypeTLS = "tls" + keyTypeSSH = "ssh" + keyTypeJWT = "jwt" + keyTypeEncryption = "enc" labelStoreType = "store_type" storePKCS11 = "pkcs11" @@ -72,6 +73,15 @@ const ( labelCryptoAlgorithm = "key_algorithm" ) +// keyUsage marks a given key to be used either with signing or decryption +type keyUsage string + +const ( + keyUsageNone keyUsage = "" + keyUsageSign keyUsage = "sign" + keyUsageDecrypt keyUsage = "decrypt" +) + var ( signCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: teleport.MetricNamespace, @@ -85,6 +95,18 @@ var ( Name: "sign_requests_error", Help: "Total number of sign request errors", }, []string{labelKeyType, labelStoreType}) + decryptCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: teleport.MetricNamespace, + Subsystem: keystoreSubsystem, + Name: "decrypt_requests_total", + Help: "Total number of decrypt requests", + }, []string{labelKeyType, labelStoreType}) + decryptErrorCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: teleport.MetricNamespace, + Subsystem: keystoreSubsystem, + Name: "decrypt_requests_error", + Help: "Total number of decrypt request errors", + }, []string{labelKeyType, labelStoreType}) createCounter = prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: teleport.MetricNamespace, Subsystem: keystoreSubsystem, @@ -106,30 +128,39 @@ type Manager struct { // use, all new keys will be generated in this backend. backendForNewKeys backend - // usableSigningBackends is a list of all backends the manager can get - // signers from, in preference order. [backendForNewKeys] is expected to be + // usableBackends is a list of all backends the manager can get signers or + // decrypters from, in preference order. [backendForNewKeys] is expected to be // the first element. - usableSigningBackends []backend + usableBackends []backend currentSuiteGetter cryptosuites.GetSuiteFunc logger *slog.Logger } -// backend is an interface that holds private keys and provides signing +// backend is an interface that holds private keys and provides signing and decryption // operations. type backend interface { - // generateRSA creates a new key pair and returns its identifier and a crypto.Signer. The returned + // generateSigner creates a new key pair and returns its identifier and a crypto.Signer. The returned // identifier can be passed to getSigner later to get an equivalent crypto.Signer. - generateKey(context.Context, cryptosuites.Algorithm) (keyID []byte, signer crypto.Signer, err error) + generateSigner(context.Context, cryptosuites.Algorithm) (keyID []byte, signer crypto.Signer, err error) + + // generateDecrypter creates a new key pair and returns its identifier and a crypto.Decrypter. The returned + // identifier can be passed to getDecrypter later to get an equivalent crypto.Decrypter. + generateDecrypter(context.Context, cryptosuites.Algorithm) (keyID []byte, decrypter crypto.Decrypter, hash crypto.Hash, err error) // getSigner returns a crypto.Signer for the given key identifier, if it is found. // The public key is passed as well so that it does not need to be fetched // from the underlying backend, and it is always stored in the CA anyway. getSigner(ctx context.Context, keyID []byte, pub crypto.PublicKey) (crypto.Signer, error) - // canSignWithKey returns true if this backend is able to sign with the + // getDecrypter returns a crypto.Decrypter for the given key identifier, if it is found. + // The public key is passed as well so that it does not need to be fetched + // from the underlying backend. + getDecrypter(ctx context.Context, keyID []byte, pub crypto.PublicKey, hash crypto.Hash) (crypto.Decrypter, error) + + // canUseKey returns true if this backend is able to sign or decrypt with the // given key. - canSignWithKey(ctx context.Context, raw []byte, keyType types.PrivateKeyType) (bool, error) + canUseKey(ctx context.Context, raw []byte, keyType types.PrivateKeyType) (bool, error) // deleteKey deletes the given key from the backend. deleteKey(ctx context.Context, keyID []byte) error @@ -145,6 +176,9 @@ type backend interface { // keys this backend uses. keyTypeDescription() string + // findDecryptersByLabel returns all known decrypters identified by the given label + findDecryptersByLabel(ctx context.Context, label *types.KeyLabel) ([]crypto.Decrypter, error) + // name returns the name of the backend. name() string } @@ -164,6 +198,8 @@ type Options struct { // RSAKeyPairSource is an optional function used by the software keystore when // generating RSA keys. RSAKeyPairSource RSAKeyPairSource + // OAEPHash function to use with keystores that support OAEP with a configurable hash. + OAEPHash crypto.Hash awsKMSClient kmsClient mrkClient mrkClient @@ -209,7 +245,7 @@ func NewManager(ctx context.Context, cfg *servicecfg.KeystoreConfig, opts *Optio softwareBackend := newSoftwareKeyStore(&softwareConfig{rsaKeyPairSource: opts.RSAKeyPairSource}) var backendForNewKeys backend = softwareBackend - usableSigningBackends := []backend{softwareBackend} + usableBackends := []backend{softwareBackend} switch { case cfg.PKCS11 != (servicecfg.PKCS11Config{}): @@ -218,28 +254,28 @@ func NewManager(ctx context.Context, cfg *servicecfg.KeystoreConfig, opts *Optio return nil, trace.Wrap(err) } backendForNewKeys = pkcs11Backend - usableSigningBackends = []backend{pkcs11Backend, softwareBackend} + usableBackends = []backend{pkcs11Backend, softwareBackend} case cfg.GCPKMS != (servicecfg.GCPKMSConfig{}): gcpBackend, err := newGCPKMSKeyStore(ctx, &cfg.GCPKMS, opts) if err != nil { return nil, trace.Wrap(err) } backendForNewKeys = gcpBackend - usableSigningBackends = []backend{gcpBackend, softwareBackend} + usableBackends = []backend{gcpBackend, softwareBackend} case cfg.AWSKMS != nil: awsBackend, err := newAWSKMSKeystore(ctx, cfg.AWSKMS, opts) if err != nil { return nil, trace.Wrap(err) } backendForNewKeys = awsBackend - usableSigningBackends = []backend{awsBackend, softwareBackend} + usableBackends = []backend{awsBackend, softwareBackend} } return &Manager{ - backendForNewKeys: backendForNewKeys, - usableSigningBackends: usableSigningBackends, - currentSuiteGetter: cryptosuites.GetCurrentSuiteFromAuthPreference(opts.AuthPreferenceGetter), - logger: opts.Logger, + backendForNewKeys: backendForNewKeys, + usableBackends: usableBackends, + currentSuiteGetter: cryptosuites.GetCurrentSuiteFromAuthPreference(opts.AuthPreferenceGetter), + logger: opts.Logger, }, nil } @@ -259,6 +295,23 @@ func (s *cryptoCountSigner) Sign(rand io.Reader, digest []byte, opts crypto.Sign return sig, nil } +type cryptoCountDecrypter struct { + crypto.Decrypter + keyType string + store string +} + +func (d *cryptoCountDecrypter) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) ([]byte, error) { + decryptCounter.WithLabelValues(d.keyType, d.store).Inc() + plaintext, err := d.Decrypter.Decrypt(rand, ciphertext, opts) + if err != nil { + decryptErrorCounter.WithLabelValues(d.keyType, d.store).Inc() + return nil, trace.Wrap(err) + } + + return plaintext, nil +} + // GetSSHSigner selects a usable SSH keypair from the given CA ActiveKeys and // returns an [ssh.Signer]. func (m *Manager) GetSSHSigner(ctx context.Context, ca types.CertAuthority) (ssh.Signer, error) { @@ -276,13 +329,13 @@ func (m *Manager) GetAdditionalTrustedSSHSigner(ctx context.Context, ca types.Ce // GetSSHSignerFromKeySet selects a usable SSH keypair from the provided key // set. func (m *Manager) GetSSHSignerFromKeySet(ctx context.Context, keySet types.CAKeySet) (ssh.Signer, error) { - for _, backend := range m.usableSigningBackends { + for _, backend := range m.usableBackends { for _, keyPair := range keySet.SSH { - canSign, err := backend.canSignWithKey(ctx, keyPair.PrivateKey, keyPair.PrivateKeyType) + canUse, err := backend.canUseKey(ctx, keyPair.PrivateKey, keyPair.PrivateKeyType) if err != nil { return nil, trace.Wrap(err) } - if !canSign { + if !canUse { continue } pub, err := publicKeyFromSSHAuthorizedKey(keyPair.PublicKey) @@ -389,8 +442,8 @@ var ErrUnusableKey = errors.New("unable to sign with requested key") // It returns ErrUnusableKey if unable to create a signer from the given keypair, // e.g. if it is stored in an HSM or KMS this auth service is not configured to use. func (m *Manager) TLSSigner(ctx context.Context, keypair *types.TLSKeyPair) (crypto.Signer, error) { - for _, backend := range m.usableSigningBackends { - canUse, err := backend.canSignWithKey(ctx, keypair.Key, keypair.KeyType) + for _, backend := range m.usableBackends { + canUse, err := backend.canUseKey(ctx, keypair.Key, keypair.KeyType) if err != nil { return nil, trace.Wrap(err) } @@ -433,13 +486,13 @@ func (m *Manager) GetAdditionalTrustedTLSCertAndSigner(ctx context.Context, ca t } func (m *Manager) getTLSCertAndSigner(ctx context.Context, keySet types.CAKeySet) ([]byte, crypto.Signer, error) { - for _, backend := range m.usableSigningBackends { + for _, backend := range m.usableBackends { for _, keyPair := range keySet.TLS { - canSign, err := backend.canSignWithKey(ctx, keyPair.Key, keyPair.KeyType) + canUse, err := backend.canUseKey(ctx, keyPair.Key, keyPair.KeyType) if err != nil { return nil, nil, trace.Wrap(err) } - if !canSign { + if !canUse { continue } pub, err := publicKeyFromTLSCertPem(keyPair.Cert) @@ -472,13 +525,13 @@ func publicKeyFromTLSCertPem(certPem []byte) (crypto.PublicKey, error) { // GetJWTSigner selects a usable JWT keypair from the given keySet and returns // a [crypto.Signer]. func (m *Manager) GetJWTSigner(ctx context.Context, ca types.CertAuthority) (crypto.Signer, error) { - for _, backend := range m.usableSigningBackends { + for _, backend := range m.usableBackends { for _, keyPair := range ca.GetActiveKeys().JWT { - canSign, err := backend.canSignWithKey(ctx, keyPair.PrivateKey, keyPair.PrivateKeyType) + canUse, err := backend.canUseKey(ctx, keyPair.PrivateKey, keyPair.PrivateKeyType) if err != nil { return nil, trace.Wrap(err) } - if !canSign { + if !canUse { continue } pub, err := keys.ParsePublicKey(keyPair.PublicKey) @@ -495,6 +548,52 @@ func (m *Manager) GetJWTSigner(ctx context.Context, ca types.CertAuthority) (cry return nil, trace.NotFound("no usable JWT key pairs found") } +// GetDecrypter returns the [crypto.Decrypter] associated with a given EncryptionKeyPair if accessible. +func (m *Manager) GetDecrypter(ctx context.Context, keyPair *types.EncryptionKeyPair) (crypto.Decrypter, error) { + for _, backend := range m.usableBackends { + canUse, err := backend.canUseKey(ctx, keyPair.PrivateKey, keyPair.PrivateKeyType) + if err != nil { + return nil, trace.Wrap(err) + } + + if !canUse { + continue + } + pub, err := x509.ParsePKIXPublicKey(keyPair.PublicKey) + if err != nil { + return nil, trace.Wrap(err) + } + + decrypter, err := backend.getDecrypter(ctx, keyPair.PrivateKey, pub, crypto.Hash(keyPair.Hash)) + if err != nil { + return nil, trace.Wrap(err) + } + + return &cryptoCountDecrypter{Decrypter: decrypter, keyType: keyTypeEncryption, store: backend.name()}, nil + } + + return nil, trace.NotFound("no compatible backend found for keypair") +} + +// FindDecryptersByLabels returns a slice of all [crypto.Decrypter] keys identified by the given labels across all +// usable backends. +func (m *Manager) FindDecryptersByLabels(ctx context.Context, labels ...*types.KeyLabel) ([]crypto.Decrypter, error) { + var decrypters []crypto.Decrypter + for _, backend := range m.usableBackends { + for _, label := range labels { + decs, err := backend.findDecryptersByLabel(ctx, label) + if err != nil { + m.logger.DebugContext(ctx, "could not find key for label", "backend", backend.name(), "label_type", label.Type, "label", label.Label, "error", err) + continue + } + + decrypters = append(decrypters, decs...) + } + } + + return decrypters, nil +} + // NewSSHKeyPair generates a new SSH keypair in the keystore backend and returns it. func (m *Manager) NewSSHKeyPair(ctx context.Context, purpose cryptosuites.KeyPurpose) (*types.SSHKeyPair, error) { alg, err := cryptosuites.AlgorithmForKey(ctx, m.currentSuiteGetter, purpose) @@ -511,7 +610,7 @@ func (m *Manager) NewSSHKeyPair(ctx context.Context, purpose cryptosuites.KeyPur } func (m *Manager) newSSHKeyPair(ctx context.Context, alg cryptosuites.Algorithm) (*types.SSHKeyPair, error) { - sshKey, signer, err := m.backendForNewKeys.generateKey(ctx, alg) + sshKey, signer, err := m.backendForNewKeys.generateSigner(ctx, alg) if err != nil { return nil, trace.Wrap(err) } @@ -542,7 +641,7 @@ func (m *Manager) NewTLSKeyPair(ctx context.Context, clusterName string, purpose } func (m *Manager) newTLSKeyPair(ctx context.Context, clusterName string, alg cryptosuites.Algorithm) (*types.TLSKeyPair, error) { - tlsKey, signer, err := m.backendForNewKeys.generateKey(ctx, alg) + tlsKey, signer, err := m.backendForNewKeys.generateSigner(ctx, alg) if err != nil { return nil, trace.Wrap(err) } @@ -627,7 +726,7 @@ func (m *Manager) NewJWTKeyPair(ctx context.Context, purpose cryptosuites.KeyPur } func (m *Manager) newJWTKeyPair(ctx context.Context, alg cryptosuites.Algorithm) (*types.JWTKeyPair, error) { - jwtKey, signer, err := m.backendForNewKeys.generateKey(ctx, alg) + jwtKey, signer, err := m.backendForNewKeys.generateSigner(ctx, alg) if err != nil { return nil, trace.Wrap(err) } @@ -642,6 +741,40 @@ func (m *Manager) newJWTKeyPair(ctx context.Context, alg cryptosuites.Algorithm) }, nil } +// NewEncryptionKeyPair creates and returns a new encryption keypair. +func (m *Manager) NewEncryptionKeyPair(ctx context.Context, purpose cryptosuites.KeyPurpose) (*types.EncryptionKeyPair, error) { + alg, err := cryptosuites.AlgorithmForKey(ctx, m.currentSuiteGetter, purpose) + if err != nil { + return nil, trace.Wrap(err) + } + + createCounter.WithLabelValues(keyTypeEncryption, m.backendForNewKeys.name(), alg.String()).Inc() + key, err := m.newEncryptionKeyPair(ctx, alg) + if err != nil { + createErrorCounter.WithLabelValues(keyTypeEncryption, m.backendForNewKeys.name(), alg.String()).Inc() + return nil, trace.Wrap(err) + } + return key, nil +} + +func (m *Manager) newEncryptionKeyPair(ctx context.Context, alg cryptosuites.Algorithm) (*types.EncryptionKeyPair, error) { + encKey, decrypter, hash, err := m.backendForNewKeys.generateDecrypter(ctx, alg) + if err != nil { + return nil, trace.Wrap(err) + } + publicKey, err := x509.MarshalPKIXPublicKey(decrypter.Public()) + if err != nil { + return nil, trace.Wrap(err) + } + + return &types.EncryptionKeyPair{ + PublicKey: publicKey, + PrivateKey: encKey, + PrivateKeyType: keyType(encKey), + Hash: uint32(hash), + }, nil +} + // UsableKeysResult holds the result of a call to HasUsableActiveKeys or // HasUsableAdditionalTrustedKeys. type UsableKeysResult struct { @@ -677,10 +810,10 @@ func (m *Manager) hasUsableKeys(ctx context.Context, keySet types.CAKeySet) (*Us PreferredKeyType: m.backendForNewKeys.keyTypeDescription(), } var allRawKeys [][]byte - for i, backend := range m.usableSigningBackends { + for i, backend := range m.usableBackends { preferredBackend := i == 0 for _, sshKeyPair := range keySet.SSH { - usable, err := backend.canSignWithKey(ctx, sshKeyPair.PrivateKey, sshKeyPair.PrivateKeyType) + usable, err := backend.canUseKey(ctx, sshKeyPair.PrivateKey, sshKeyPair.PrivateKeyType) if err != nil { return nil, trace.Wrap(err) } @@ -694,7 +827,7 @@ func (m *Manager) hasUsableKeys(ctx context.Context, keySet types.CAKeySet) (*Us allRawKeys = append(allRawKeys, sshKeyPair.PrivateKey) } for _, tlsKeyPair := range keySet.TLS { - usable, err := backend.canSignWithKey(ctx, tlsKeyPair.Key, tlsKeyPair.KeyType) + usable, err := backend.canUseKey(ctx, tlsKeyPair.Key, tlsKeyPair.KeyType) if err != nil { return nil, trace.Wrap(err) } @@ -708,7 +841,7 @@ func (m *Manager) hasUsableKeys(ctx context.Context, keySet types.CAKeySet) (*Us allRawKeys = append(allRawKeys, tlsKeyPair.Key) } for _, jwtKeyPair := range keySet.JWT { - usable, err := backend.canSignWithKey(ctx, jwtKeyPair.PrivateKey, jwtKeyPair.PrivateKeyType) + usable, err := backend.canUseKey(ctx, jwtKeyPair.PrivateKey, jwtKeyPair.PrivateKeyType) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/auth/keystore/pkcs11.go b/lib/auth/keystore/pkcs11.go index 2184e4afce7a2..ba92f1bfc2fca 100644 --- a/lib/auth/keystore/pkcs11.go +++ b/lib/auth/keystore/pkcs11.go @@ -22,6 +22,7 @@ import ( "context" "crypto" "crypto/elliptic" + "encoding/binary" "encoding/hex" "encoding/json" "fmt" @@ -37,16 +38,22 @@ import ( "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/cryptosuites" "github.com/gravitational/teleport/lib/service/servicecfg" + logutils "github.com/gravitational/teleport/lib/utils/log" ) var pkcs11Prefix = []byte("pkcs11:") +const ( + recordingEncryptionHostID = "teleport_recording_encryption" +) + type pkcs11KeyStore struct { ctx *crypto11.Context hostUUID string log *slog.Logger isYubiHSM bool semaphore chan struct{} + oaepHash crypto.Hash } func newPKCS11KeyStore(config *servicecfg.PKCS11Config, opts *Options) (*pkcs11KeyStore, error) { @@ -69,12 +76,18 @@ func newPKCS11KeyStore(config *servicecfg.PKCS11Config, opts *Options) (*pkcs11K return nil, trace.Wrap(err, "getting PKCS#11 module info") } + oaepHash := crypto.SHA256 + if opts.OAEPHash != crypto.Hash(0) { + oaepHash = opts.OAEPHash + } + return &pkcs11KeyStore{ ctx: ctx, hostUUID: opts.HostUUID, log: opts.Logger, isYubiHSM: strings.HasPrefix(info.ManufacturerID, "Yubico"), semaphore: make(chan struct{}, 1), + oaepHash: oaepHash, }, nil } @@ -122,9 +135,9 @@ func (p *pkcs11KeyStore) findUnusedID(ctx context.Context) (keyID, error) { return keyID{}, trace.AlreadyExists("failed to find unused CKA_ID for HSM") } -// generateKey creates a new private key and returns its identifier and a crypto.Signer. The returned +// generateSigner creates a new private key and returns its identifier and a crypto.Signer. The returned // identifier can be passed to getSigner later to get an equivalent crypto.Signer. -func (p *pkcs11KeyStore) generateKey(ctx context.Context, alg cryptosuites.Algorithm) ([]byte, crypto.Signer, error) { +func (p *pkcs11KeyStore) generateSigner(ctx context.Context, alg cryptosuites.Algorithm) ([]byte, crypto.Signer, error) { // The key identifiers are not created in a thread safe // manner so all calls are serialized to prevent races. select { @@ -151,13 +164,16 @@ func (p *pkcs11KeyStore) generateKey(ctx context.Context, alg cryptosuites.Algor return nil, nil, trace.Wrap(err) } - p.log.InfoContext(ctx, "Creating new HSM keypair.", "id", id, "algorithm", alg.String()) + p.log.InfoContext(ctx, "Creating new HSM keypair.", "id", id, "algorithm", logutils.StringerAttr(alg)) label := []byte(p.hostUUID) switch alg { case cryptosuites.RSA2048: signer, err := p.generateRSA2048(rawPKCS11ID, label) return rawTeleportID, signer, trace.Wrap(err, "generating RSA2048 key") + case cryptosuites.RSA4096: + signer, err := p.generateRSA4096(rawPKCS11ID, label) + return rawTeleportID, signer, trace.Wrap(err, "generating RSA4096 key") case cryptosuites.ECDSAP256: signer, err := p.generateECDSAP256(rawPKCS11ID, label) return rawTeleportID, signer, trace.Wrap(err, "generating ECDSAP256 key") @@ -166,11 +182,58 @@ func (p *pkcs11KeyStore) generateKey(ctx context.Context, alg cryptosuites.Algor } } -func (p *pkcs11KeyStore) generateRSA2048(ckaID, label []byte) (crypto.Signer, error) { +// generateDecrypter creates a new private key and returns its identifier and a crypto.Decrypter. The returned +// identifier can be passed to getDecrypter later to get an equivalent crypto.Decrypter. +func (p *pkcs11KeyStore) generateDecrypter(ctx context.Context, alg cryptosuites.Algorithm) ([]byte, crypto.Decrypter, crypto.Hash, error) { + // The key identifiers are not created in a thread safe + // manner so all calls are serialized to prevent races. + select { + case p.semaphore <- struct{}{}: + case <-ctx.Done(): + return nil, nil, p.oaepHash, trace.Wrap(ctx.Err()) + } + defer func() { + <-p.semaphore + }() + + id, err := p.findUnusedID(ctx) + if err != nil { + return nil, nil, p.oaepHash, trace.Wrap(err) + } + + id.HostID = recordingEncryptionHostID + rawTeleportID, err := id.marshal() + if err != nil { + return nil, nil, p.oaepHash, trace.Wrap(err) + } + + rawPKCS11ID, err := id.pkcs11Key(p.isYubiHSM) + if err != nil { + return nil, nil, p.oaepHash, trace.Wrap(err) + } + + p.log.InfoContext(ctx, "Creating new HSM keypair.", "id", id, "algorithm", logutils.StringerAttr(alg)) + + label := []byte(id.HostID) + switch alg { + case cryptosuites.RSA4096: + decrypter, err := p.generateRSA4096(rawPKCS11ID, label) + return rawTeleportID, newOAEPDecrypter(p.oaepHash, decrypter), p.oaepHash, trace.Wrap(err, "generating RSA4096 key") + default: + return nil, nil, p.oaepHash, trace.BadParameter("unsupported key algorithm for PKCS#11 HSM decryption: %v", alg) + } +} + +func (p *pkcs11KeyStore) generateRSA2048(ckaID, label []byte) (crypto11.SignerDecrypter, error) { signer, err := p.ctx.GenerateRSAKeyPairWithLabel(ckaID, label, constants.RSAKeySize) return signer, trace.Wrap(err) } +func (p *pkcs11KeyStore) generateRSA4096(ckaID, label []byte) (crypto11.SignerDecrypter, error) { + signer, err := p.ctx.GenerateRSAKeyPairWithLabel(ckaID, label, 4096) + return signer, trace.Wrap(err) +} + func (p *pkcs11KeyStore) generateECDSAP256(ckaID, label []byte) (crypto.Signer, error) { signer, err := p.ctx.GenerateECDSAKeyPairWithLabel(ckaID, label, elliptic.P256()) return signer, trace.Wrap(err) @@ -181,6 +244,86 @@ func (p *pkcs11KeyStore) getSigner(ctx context.Context, rawKey []byte, publicKey return p.getSignerWithoutPublicKey(ctx, rawKey) } +// getDecrypter returns a crypto.Decrypter for the given key identifier, if it is found. +func (p *pkcs11KeyStore) getDecrypter(ctx context.Context, rawKey []byte, publicKey crypto.PublicKey, hash crypto.Hash) (crypto.Decrypter, error) { + signer, err := p.getSignerWithoutPublicKey(ctx, rawKey) + if err != nil { + return nil, trace.Wrap(err) + } + + if decrypter, ok := signer.(crypto.Decrypter); ok { + return newOAEPDecrypter(hash, decrypter), nil + } + + return nil, trace.BadParameter("pkcs11 key does not support decryption") +} + +func attrValToUint(value []byte) uint64 { + if len(value) == 4 { + return uint64(binary.BigEndian.Uint32(value)) + } + + if len(value) == 8 { + return binary.BigEndian.Uint64(value) + } + + return 0 +} + +func (p *pkcs11KeyStore) validateKeyForDecryption(signer crypto.Signer) error { + keyTypeAttr, err := p.ctx.GetAttribute(signer, crypto11.CkaKeyType) + if err != nil { + return trace.Wrap(err, "looking up key type") + } + + if attrValToUint(keyTypeAttr.Value) != pkcs11.CKK_RSA { + return trace.Errorf("invalid key algorithm, expected RSA") + } + + modAttr, err := p.ctx.GetAttribute(signer, crypto11.CkaModulus) + if err != nil { + return trace.Wrap(err, "looking up modulus") + } + + bitLen := len(modAttr.Value) * 8 + if bitLen != 4096 { + return trace.Errorf("expected 4096-bit key, found %d-bit key", bitLen) + } + + return nil +} + +func (p *pkcs11KeyStore) findDecryptersByLabel(ctx context.Context, label *types.KeyLabel) ([]crypto.Decrypter, error) { + if label == nil || label.Type != storePKCS11 { + return nil, nil + } + + signers, err := p.ctx.FindKeyPairs(nil, []byte(label.Label)) + if err != nil { + return nil, trace.Wrap(err) + } + + var decrypters []crypto.Decrypter + for _, signer := range signers { + if err := p.validateKeyForDecryption(signer); err != nil { + p.log.DebugContext(ctx, "key found but could not be used for decryption", "label_type", label.Type, "label", label.Label, "error", err) + continue + } + + decrypter, ok := signer.(crypto.Decrypter) + if !ok { + continue + } + decrypters = append(decrypters, decrypter) + } + + return decrypters, nil +} + +func (p *pkcs11KeyStore) checkAccessibleHostID(hostID string) bool { + return hostID == recordingEncryptionHostID || hostID == p.hostUUID +} + func (p *pkcs11KeyStore) getSignerWithoutPublicKey(ctx context.Context, rawKey []byte) (crypto.Signer, error) { if t := keyType(rawKey); t != types.PrivateKeyType_PKCS11 { return nil, trace.BadParameter("pkcs11KeyStore cannot get signer for key type %s", t.String()) @@ -189,14 +332,14 @@ func (p *pkcs11KeyStore) getSignerWithoutPublicKey(ctx context.Context, rawKey [ if err != nil { return nil, trace.Wrap(err) } - if keyID.HostID != p.hostUUID { + if !p.checkAccessibleHostID(keyID.HostID) { return nil, trace.NotFound("given pkcs11 key is for host: %q, but this host is: %q", keyID.HostID, p.hostUUID) } pkcs11ID, err := keyID.pkcs11Key(p.isYubiHSM) if err != nil { return nil, trace.Wrap(err) } - signer, err := p.ctx.FindKeyPair(pkcs11ID, []byte(p.hostUUID)) + signer, err := p.ctx.FindKeyPair(pkcs11ID, []byte(keyID.HostID)) if err != nil { return nil, trace.Wrap(err) } @@ -206,11 +349,11 @@ func (p *pkcs11KeyStore) getSignerWithoutPublicKey(ctx context.Context, rawKey [ return signer, nil } -// canSignWithKey returns true if the given key is PKCS11 and was created by +// canUseKey returns true if the given key is PKCS11 and was created by // this host. If the HSM is disconnected or the key material has been deleted -// the error will not be detected here but when the first signature is -// attempted. -func (p *pkcs11KeyStore) canSignWithKey(ctx context.Context, raw []byte, keyType types.PrivateKeyType) (bool, error) { +// the error will not be detected here but when the first signature or +// decryption is attempted. +func (p *pkcs11KeyStore) canUseKey(ctx context.Context, raw []byte, keyType types.PrivateKeyType) (bool, error) { if keyType != types.PrivateKeyType_PKCS11 { return false, nil } @@ -218,7 +361,8 @@ func (p *pkcs11KeyStore) canSignWithKey(ctx context.Context, raw []byte, keyType if err != nil { return false, trace.Wrap(err) } - return keyID.HostID == p.hostUUID, nil + + return p.checkAccessibleHostID(keyID.HostID), nil } // deleteKey deletes the given key from the HSM @@ -227,7 +371,7 @@ func (p *pkcs11KeyStore) deleteKey(_ context.Context, rawKey []byte) error { if err != nil { return trace.Wrap(err) } - if keyID.HostID != p.hostUUID { + if !p.checkAccessibleHostID(keyID.HostID) { return trace.NotFound("pkcs11 key is for different host") } pkcs11ID, err := keyID.pkcs11Key(p.isYubiHSM) @@ -264,7 +408,7 @@ func (p *pkcs11KeyStore) deleteUnusedKeys(ctx context.Context, activeKeys [][]by if err != nil { return trace.Wrap(err) } - if keyID.HostID != p.hostUUID { + if !p.checkAccessibleHostID(keyID.HostID) { // This key was labeled with a foreign host UUID, it is likely not // present on the attached HSM and definitely will not be returned // by FindKeyPairs below which queries by host UUID. @@ -368,5 +512,6 @@ func parsePKCS11KeyID(key []byte) (keyID, error) { if err := json.Unmarshal(key, &keyID); err != nil { return keyID, trace.Wrap(err) } + return keyID, nil } diff --git a/lib/auth/keystore/software.go b/lib/auth/keystore/software.go index fff5e6dace9ac..55e8f62a7d898 100644 --- a/lib/auth/keystore/software.go +++ b/lib/auth/keystore/software.go @@ -21,6 +21,9 @@ package keystore import ( "context" "crypto" + "crypto/rsa" + "crypto/x509" + "io" "github.com/gravitational/trace" @@ -29,12 +32,14 @@ import ( "github.com/gravitational/teleport/lib/cryptosuites" ) +const softwareHash = crypto.SHA256 + type softwareKeyStore struct { rsaKeyPairSource RSAKeyPairSource } // RSAKeyPairSource is a function type which returns new RSA keypairs. -type RSAKeyPairSource func() (priv []byte, pub []byte, err error) +type RSAKeyPairSource func(alg cryptosuites.Algorithm) (priv []byte, pub []byte, err error) type softwareConfig struct { rsaKeyPairSource RSAKeyPairSource @@ -56,18 +61,19 @@ func (s *softwareKeyStore) keyTypeDescription() string { return "raw software keys" } -// generateRSA creates a new private key and returns its identifier and a crypto.Signer. The returned +// generateSigner creates a new private key and returns its identifier and a crypto.Signer. The returned // identifier for softwareKeyStore is a pem-encoded private key, and can be passed to getSigner later to get // an equivalent crypto.Signer. -func (s *softwareKeyStore) generateKey(ctx context.Context, alg cryptosuites.Algorithm) ([]byte, crypto.Signer, error) { +func (s *softwareKeyStore) generateSigner(ctx context.Context, alg cryptosuites.Algorithm) ([]byte, crypto.Signer, error) { if alg == cryptosuites.RSA2048 && s.rsaKeyPairSource != nil { - privateKeyPEM, _, err := s.rsaKeyPairSource() + privateKeyPEM, _, err := s.rsaKeyPairSource(alg) if err != nil { return nil, nil, err } - signer, err := keys.ParsePrivateKey(privateKeyPEM) - return privateKeyPEM, signer, trace.Wrap(err) + privateKey, err := keys.ParsePrivateKey(privateKeyPEM) + return privateKeyPEM, privateKey, trace.Wrap(err) } + signer, err := cryptosuites.GenerateKeyWithAlgorithm(alg) if err != nil { return nil, nil, err @@ -76,13 +82,98 @@ func (s *softwareKeyStore) generateKey(ctx context.Context, alg cryptosuites.Alg return privateKeyPEM, signer, trace.Wrap(err) } +// oaepDecrypter captures and supplies the default opts that should be provided +// at decryption time for convenience +type oaepDecrypter struct { + crypto.Decrypter + hash crypto.Hash +} + +func newOAEPDecrypter(hash crypto.Hash, decrypter crypto.Decrypter) oaepDecrypter { + return oaepDecrypter{ + Decrypter: decrypter, + hash: hash, + } +} + +func (d oaepDecrypter) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) ([]byte, error) { + if opts == nil { + opts = &rsa.OAEPOptions{ + Hash: d.hash, + } + } + + plaintext, err := d.Decrypter.Decrypt(rand, ciphertext, opts) + return plaintext, trace.Wrap(err) +} + +// generateDecrypter creates a new private key and returns its identifier and a [crypto.Decrypter]. The returned +// identifier for softwareKeyStore is a pem-encoded private key, and can be passed to getDecrypter later to get +// an equivalent crypto.Decrypter. +func (s *softwareKeyStore) generateDecrypter(ctx context.Context, alg cryptosuites.Algorithm) ([]byte, crypto.Decrypter, crypto.Hash, error) { + if alg == cryptosuites.RSA4096 && s.rsaKeyPairSource != nil { + privateKeyPEM, _, err := s.rsaKeyPairSource(alg) + if err != nil { + return nil, nil, softwareHash, trace.Wrap(err) + } + + privateKey, err := keys.ParsePrivateKey(privateKeyPEM) + if err != nil { + return nil, nil, softwareHash, trace.Wrap(err) + } + + decrypter, ok := privateKey.Signer.(crypto.Decrypter) + if !ok { + return nil, nil, softwareHash, trace.Errorf("could not type assert crypto.Decrypter") + } + + privateKeyDER, err := x509.MarshalPKCS8PrivateKey(privateKey.Signer) + if err != nil { + return nil, nil, softwareHash, trace.Wrap(err) + } + + return privateKeyDER, newOAEPDecrypter(softwareHash, decrypter), softwareHash, trace.Wrap(err) + } + + key, err := cryptosuites.GenerateDecrypterWithAlgorithm(alg) + if err != nil { + return nil, nil, softwareHash, trace.Wrap(err) + } + + privateKey, err := x509.MarshalPKCS8PrivateKey(key) + if err != nil { + return nil, nil, softwareHash, trace.Wrap(err) + } + + return privateKey, newOAEPDecrypter(softwareHash, key), softwareHash, trace.Wrap(err) +} + // getSigner returns a crypto.Signer for the given pem-encoded private key. func (s *softwareKeyStore) getSigner(ctx context.Context, rawKey []byte, publicKey crypto.PublicKey) (crypto.Signer, error) { return keys.ParsePrivateKey(rawKey) } -// canSignWithKey returns true if the given key is a raw key. -func (s *softwareKeyStore) canSignWithKey(ctx context.Context, _ []byte, keyType types.PrivateKeyType) (bool, error) { +// getDecrypter returns a crypto.Decrypter for the given pem-encoded private key. +func (s *softwareKeyStore) getDecrypter(ctx context.Context, rawKey []byte, publicKey crypto.PublicKey, hash crypto.Hash) (crypto.Decrypter, error) { + privateKey, err := x509.ParsePKCS8PrivateKey(rawKey) + if err != nil { + return nil, trace.Wrap(err) + } + + decrypter, ok := privateKey.(crypto.Decrypter) + if !ok { + return nil, trace.Errorf("unsupported encryption key type %T", privateKey) + } + + return newOAEPDecrypter(softwareHash, decrypter), nil +} + +func (s *softwareKeyStore) findDecryptersByLabel(ctx context.Context, label *types.KeyLabel) ([]crypto.Decrypter, error) { + return nil, trace.NotImplemented("software decryption keys do not support lookup by label") +} + +// canUseKey returns true if the given key is a raw key. +func (s *softwareKeyStore) canUseKey(ctx context.Context, _ []byte, keyType types.PrivateKeyType) (bool, error) { return keyType == types.PrivateKeyType_RAW, nil } diff --git a/lib/auth/recordingencryption/age.go b/lib/auth/recordingencryption/age.go new file mode 100644 index 0000000000000..e8f71673f2e61 --- /dev/null +++ b/lib/auth/recordingencryption/age.go @@ -0,0 +1,146 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package recordingencryption + +import ( + "context" + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "io" + + "filippo.io/age" + "github.com/gravitational/trace" +) + +// RecordingStanza is the type used for the identifying stanza added by RecordingRecipient. +const RecordingStanza = "teleport-recording-rsa4096" + +// UnwrapInput represents a request to decrypt a wrapped file key. +type UnwrapInput struct { + // Fingerprint of the public key used to find the related private key. + Fingerprint string + // WrappedKey is the encrypted file key in an encrypted recording stanza. + WrappedKey []byte + + // Rand reader to pass to use during decryption. + Rand io.Reader + // Opts that should be used during decryption. + Opts crypto.DecrypterOpts +} + +// KeyUnwrapper returns an unwrapped file key given a wrapped key and a fingerprint of the encryption key. +type KeyUnwrapper interface { + UnwrapKey(ctx context.Context, in UnwrapInput) ([]byte, error) +} + +// RecordingIdentity unwraps file keys using the configured [KeyUnwrapper] and the recording stanzas +// included in the age header. +type RecordingIdentity struct { + ctx context.Context + unwrapper KeyUnwrapper +} + +// NewRecordingIdentity returns a new RecordingIdentity using the given [KeyUnwrapper] +// file key unwrapping. +func NewRecordingIdentity(ctx context.Context, unwrapper KeyUnwrapper) *RecordingIdentity { + return &RecordingIdentity{ + ctx: ctx, + unwrapper: unwrapper, + } +} + +// Unwrap uses the additional stanzas added by [RecordingRecipient.Wrap] in order to find a matching RSA 4096 +// private key. +func (i *RecordingIdentity) Unwrap(stanzas []*age.Stanza) ([]byte, error) { + var errs []error + for _, stanza := range stanzas { + if stanza.Type != RecordingStanza { + continue + } + + if len(stanza.Args) != 1 { + continue + } + + fileKey, err := i.unwrapper.UnwrapKey(i.ctx, UnwrapInput{ + Rand: rand.Reader, + WrappedKey: stanza.Body, + Fingerprint: stanza.Args[0], + Opts: &rsa.OAEPOptions{ + Hash: crypto.SHA256, + }, + }) + if err != nil { + if !trace.IsNotFound(err) { + errs = append(errs, err) + } + continue + } + + return fileKey, nil + } + + if len(errs) == 0 { + return nil, trace.Errorf("could not find an accessible decrypter for unwrapping") + } + return nil, trace.NewAggregate(errs...) +} + +// RecordingRecipient wraps file keys using an RSA 40960public key. +type RecordingRecipient struct { + *rsa.PublicKey +} + +// ParseRecordingRecipient parses a PEM encoded RSA 4096 public key into a RecordingRecipient. +func ParseRecordingRecipient(in []byte) (*RecordingRecipient, error) { + pubKey, err := x509.ParsePKIXPublicKey(in) + if err != nil { + return nil, trace.Wrap(err) + } + + rsaKey, ok := pubKey.(*rsa.PublicKey) + if !ok { + return nil, trace.BadParameter("recording encryption key must be a public RSA 4096") + } + + return &RecordingRecipient{PublicKey: rsaKey}, nil +} + +// Wrap a fileKey using an RSA public key. The fingerprint of the key will be included in the stanza +// to aid in fetching the correct private key during [Unwrap]. +func (r *RecordingRecipient) Wrap(fileKey []byte) ([]*age.Stanza, error) { + cipher, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, r.PublicKey, fileKey, nil) + if err != nil { + return nil, trace.Wrap(err) + } + + fp, err := Fingerprint(r.PublicKey) + if err != nil { + return nil, trace.Wrap(err) + } + + return []*age.Stanza{ + { + Type: RecordingStanza, + Args: []string{fp}, + Body: cipher, + }, + }, nil +} diff --git a/lib/auth/recordingencryption/age_test.go b/lib/auth/recordingencryption/age_test.go new file mode 100644 index 0000000000000..773e5c2324f96 --- /dev/null +++ b/lib/auth/recordingencryption/age_test.go @@ -0,0 +1,77 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package recordingencryption_test + +import ( + "bytes" + "io" + "testing" + + "filippo.io/age" + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth/recordingencryption" +) + +func TestRecordingAgePlugin(t *testing.T) { + ctx := t.Context() + keyStore := newFakeKeyStore(types.PrivateKeyType_RAW) + recordingIdentity := recordingencryption.NewRecordingIdentity(ctx, keyStore) + + _, pubKey, err := keyStore.createKey() + require.NoError(t, err) + + recipient, err := recordingencryption.ParseRecordingRecipient(pubKey) + require.NoError(t, err) + + out := bytes.NewBuffer(nil) + writer, err := age.Encrypt(out, recipient) + require.NoError(t, err) + + msg := []byte("testing age plugin for session recordings") + _, err = writer.Write(msg) + require.NoError(t, err) + + // writer must be closed to ensure data is flushed + err = writer.Close() + require.NoError(t, err) + + // decrypted text should match original msg + reader, err := age.Decrypt(out, recordingIdentity) + require.NoError(t, err) + plaintext, err := io.ReadAll(reader) + require.NoError(t, err) + + require.Equal(t, msg, plaintext) + + // running the same test with an unknown public key should fail + _, pubKey, err = keyStore.genKeys() + require.NoError(t, err) + + recipient, err = recordingencryption.ParseRecordingRecipient(pubKey) + require.NoError(t, err) + out.Reset() + writer, err = age.Encrypt(out, recipient) + require.NoError(t, err) + _, err = writer.Write(msg) + require.NoError(t, err) + err = writer.Close() + require.NoError(t, err) + _, err = age.Decrypt(out, recordingIdentity) + require.Error(t, err) +} diff --git a/lib/auth/recordingencryption/encryptedio.go b/lib/auth/recordingencryption/encryptedio.go new file mode 100644 index 0000000000000..676e957246259 --- /dev/null +++ b/lib/auth/recordingencryption/encryptedio.go @@ -0,0 +1,147 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package recordingencryption + +import ( + "context" + "io" + + "filippo.io/age" + "github.com/gravitational/trace" + + "github.com/gravitational/teleport/api/types" +) + +// SessionRecordingConfigGetter returns the types.SessionRecordingConfig used to determine if +// encryption is enabled and retrieve the encryption keys to use +type SessionRecordingConfigGetter interface { + GetSessionRecordingConfig(ctx context.Context) (types.SessionRecordingConfig, error) +} + +// EncryptedIO wraps a SessionRecordingConfigGetter and a recordingencryption.DecryptionKeyFinder in order +// to provide encryption and decryption wrapping backed by cluster resources +type EncryptedIO struct { + srcGetter SessionRecordingConfigGetter + unwrapper KeyUnwrapper +} + +// NewEncryptedIO returns an EncryptedIO configured with the given SessionRecordingConfigGetter and +// recordingencryption.DecryptionKeyFinder +func NewEncryptedIO(srcGetter SessionRecordingConfigGetter, unwrapper KeyUnwrapper) (*EncryptedIO, error) { + switch { + case srcGetter == nil: + return nil, trace.BadParameter("SessionRecordingConfigGetter is required for EncryptedIO") + case unwrapper == nil: + return nil, trace.BadParameter("DecryptionKeyFinder is required for EncryptedIO") + } + return &EncryptedIO{ + srcGetter: srcGetter, + unwrapper: unwrapper, + }, nil +} + +// WithEncryption wraps the given io.WriteCloser with encryption using the keys present in the +// retrieved types.SessionRecordingConfig +func (e *EncryptedIO) WithEncryption(ctx context.Context, writer io.WriteCloser) (io.WriteCloser, error) { + src, err := e.srcGetter.GetSessionRecordingConfig(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + encrypter := NewEncryptionWrapper(src) + w, err := encrypter.WithEncryption(ctx, writer) + return w, trace.Wrap(err) +} + +// WithDecryption wraps the given io.Reader with decryption using the recordingencryption.RecordingIdentity. This +// will dynamically search for an accessible decryption key using the provided recordingencryption.DecryptionKeyFinder +// in order to perform decryption +func (e *EncryptedIO) WithDecryption(ctx context.Context, reader io.Reader) (io.Reader, error) { + ident := NewRecordingIdentity(ctx, e.unwrapper) + r, err := age.Decrypt(reader, ident) + if err != nil { + return nil, trace.Wrap(err) + } + + return r, nil +} + +// EncryptionWrapper provides a wrapper for recording data using the keys present in the given +// types.SessionRecordingConfig +type EncryptionWrapper struct { + config types.SessionRecordingConfig +} + +// NewEncryptionWrapper returns a new EncryptionWrapper backed by the given types.SessionRecordingConfig +func NewEncryptionWrapper(sessionRecordingConfig types.SessionRecordingConfig) *EncryptionWrapper { + return &EncryptionWrapper{ + config: sessionRecordingConfig, + } +} + +// ErrEncryptionDisabled signals that the [types.SessionRecordingConfig] does not enable encryption. +var ErrEncryptionDisabled = &trace.BadParameterError{Message: "session_recording_config does not enable encryption"} + +// WithEncryption wraps the given io.WriteCloser with encryption using the keys present in the +// configured types.SessionRecordingConfig +func (s *EncryptionWrapper) WithEncryption(ctx context.Context, writer io.WriteCloser) (io.WriteCloser, error) { + if !s.config.GetEncrypted() { + return nil, trace.Wrap(ErrEncryptionDisabled) + } + + var recipients []age.Recipient + for _, key := range s.config.GetEncryptionKeys() { + recipient, err := ParseRecordingRecipient(key.PublicKey) + if err != nil { + return nil, trace.Wrap(err) + } + + recipients = append(recipients, recipient) + } + + return &ageWriter{ + w: writer, + recipients: recipients, + }, nil +} + +// ageWriter defers initializing the age encrypter to the first write so we can +// prevent age from immediately writing the header +type ageWriter struct { + w io.WriteCloser + recipients []age.Recipient + initialized bool +} + +// Write data using age encryption, initializing the encrypter if needed +func (a *ageWriter) Write(data []byte) (int, error) { + if !a.initialized { + w, err := age.Encrypt(a.w, a.recipients...) + if err != nil { + return 0, trace.Wrap(err) + } + a.w = w + a.initialized = true + } + + return a.w.Write(data) +} + +// Close flushes any buffered encrypted data and closes the underlying io.WriteCloser +func (a *ageWriter) Close() error { + return a.w.Close() +} diff --git a/lib/auth/recordingencryption/encryptedio_test.go b/lib/auth/recordingencryption/encryptedio_test.go new file mode 100644 index 0000000000000..3ace3a06b1868 --- /dev/null +++ b/lib/auth/recordingencryption/encryptedio_test.go @@ -0,0 +1,117 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package recordingencryption_test + +import ( + "bytes" + "context" + "io" + "slices" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth/recordingencryption" +) + +func TestEncryptedIO(t *testing.T) { + ctx := t.Context() + keyStore := newFakeKeyStore(types.PrivateKeyType_RAW) + _, publicKey, err := keyStore.createKey() + require.NoError(t, err) + + srcGetter, err := newFakeSRCGetter(true, []*types.AgeEncryptionKey{ + { + PublicKey: publicKey, + }, + }) + require.NoError(t, err) + + encryptedIO, err := recordingencryption.NewEncryptedIO(srcGetter, keyStore) + require.NoError(t, err) + + out := bytes.NewBuffer(nil) + writer, err := encryptedIO.WithEncryption(ctx, &writeCloser{Writer: out}) + require.NoError(t, err) + + msg := []byte("testing encrypted IO") + _, err = writer.Write(msg) + require.NoError(t, err) + + // writer must be closed to ensure data is flushed + err = writer.Close() + require.NoError(t, err) + + reader, err := encryptedIO.WithDecryption(ctx, out) + require.NoError(t, err) + + plaintext, err := io.ReadAll(reader) + require.NoError(t, err) + + require.Equal(t, msg, plaintext) + + // creating an EncryptedIO without a SessionRecordingConfigGetter or keyfinder should be an error + _, err = recordingencryption.NewEncryptedIO(nil, nil) + require.Error(t, err) + _, err = recordingencryption.NewEncryptedIO(srcGetter, nil) + require.Error(t, err) + + // wrapping encryption when encryption is disabled should return an ErrEncryptionDisabled + srcGetter, err = newFakeSRCGetter(false, nil) + require.NoError(t, err) + encryptedIO, err = recordingencryption.NewEncryptedIO(srcGetter, keyStore) + require.NoError(t, err) + + _, err = encryptedIO.WithEncryption(ctx, &writeCloser{Writer: out}) + require.ErrorIs(t, err, recordingencryption.ErrEncryptionDisabled) +} + +type fakeSRCGetter struct { + config types.SessionRecordingConfig +} + +func newFakeSRCGetter(encrypted bool, keys []*types.AgeEncryptionKey) (*fakeSRCGetter, error) { + spec := types.SessionRecordingConfigSpecV2{ + Encryption: &types.SessionRecordingEncryptionConfig{ + Enabled: encrypted, + }, + } + + config, err := types.NewSessionRecordingConfigFromConfigFile(spec) + if err != nil { + return nil, err + } + + config.SetEncryptionKeys(slices.Values(keys)) + + return &fakeSRCGetter{ + config: config, + }, nil +} + +func (f *fakeSRCGetter) GetSessionRecordingConfig(ctx context.Context) (types.SessionRecordingConfig, error) { + return f.config, nil +} + +type writeCloser struct { + io.Writer +} + +func (w *writeCloser) Close() error { + return nil +} diff --git a/lib/auth/recordingencryption/manager.go b/lib/auth/recordingencryption/manager.go new file mode 100644 index 0000000000000..8121304868745 --- /dev/null +++ b/lib/auth/recordingencryption/manager.go @@ -0,0 +1,806 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package recordingencryption + +import ( + "context" + "crypto" + "crypto/sha256" + "crypto/x509" + "encoding/hex" + "iter" + "log/slog" + "slices" + "time" + + "github.com/gravitational/trace" + + "github.com/gravitational/teleport" + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils/retryutils" + "github.com/gravitational/teleport/lib/backend" + "github.com/gravitational/teleport/lib/cryptosuites" + "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/teleport/lib/utils" +) + +// KeyStore provides methods for interacting with encryption keys. +type KeyStore interface { + NewEncryptionKeyPair(ctx context.Context, purpose cryptosuites.KeyPurpose) (*types.EncryptionKeyPair, error) + GetDecrypter(ctx context.Context, keyPair *types.EncryptionKeyPair) (crypto.Decrypter, error) + FindDecryptersByLabels(ctx context.Context, labels ...*types.KeyLabel) ([]crypto.Decrypter, error) +} + +// A Cache fetches a cached [*recordingencryptionv1.RecordingEncryption]. +type Cache interface { + GetRecordingEncryption(context.Context) (*recordingencryptionv1.RecordingEncryption, error) +} + +// ManagerConfig captures all of the dependencies required to instantiate a Manager. +type ManagerConfig struct { + Backend services.RecordingEncryption + ClusterConfig services.ClusterConfigurationInternal + KeyStore KeyStore + Cache Cache + Logger *slog.Logger + LockConfig backend.RunWhileLockedConfig + ManualKeyManagementConfig *types.ManualKeyManagementConfig + InitialSessionRecordingConfig types.SessionRecordingConfig +} + +// NewManager returns a new Manager using the given [ManagerConfig]. +func NewManager(ctx context.Context, cfg ManagerConfig) (*Manager, error) { + switch { + case cfg.Backend == nil: + return nil, trace.BadParameter("backend is required") + case cfg.ClusterConfig == nil: + return nil, trace.BadParameter("cluster config is required") + case cfg.KeyStore == nil: + return nil, trace.BadParameter("key store is required") + case cfg.Cache == nil: + return nil, trace.BadParameter("cache is required") + } + + if cfg.Logger == nil { + cfg.Logger = slog.With(teleport.ComponentKey, "recording-encryption-manager") + } + + mgr := &Manager{ + RecordingEncryption: cfg.Backend, + ClusterConfigurationInternal: cfg.ClusterConfig, + + ctx: ctx, + cache: cfg.Cache, + keyStore: cfg.KeyStore, + lockConfig: cfg.LockConfig, + logger: cfg.Logger, + manualKeyConfig: cfg.ManualKeyManagementConfig, + } + + if cfg.InitialSessionRecordingConfig != nil { + manualKeyCfg := getManualKeyManagement(cfg.InitialSessionRecordingConfig.GetEncryptionConfig()) + if manualKeyCfg != nil { + if _, err := mgr.ensureManualEncryptionKeys(ctx, *manualKeyCfg); err != nil { + return nil, trace.Wrap(err) + } + } + } + + return mgr, nil +} + +// A Manager wraps a services.RecordingEncryption and KeyStore in order to provide more complex operations +// than the CRUD methods exposed by services.RecordingEncryption. It primarily handles resolving RecordingEncryption +// state and searching for accessible decryption keys. +type Manager struct { + services.RecordingEncryption + services.ClusterConfigurationInternal + + ctx context.Context + cache Cache + keyStore KeyStore + keyCache utils.SyncMap[string, crypto.Decrypter] + lockConfig backend.RunWhileLockedConfig + logger *slog.Logger + manualKeyConfig *types.ManualKeyManagementConfig +} + +// CreateSessionRecordingConfig creates a new session recording configuration. If encryption is enabled then an +// accessible encryption key pair will be confirmed. Either creating one if none exists, doing nothing if one is +// accessible, or returning an error if none are accessible. +func (m *Manager) CreateSessionRecordingConfig(ctx context.Context, cfg types.SessionRecordingConfig) (types.SessionRecordingConfig, error) { + sessionRecordingConfig, err := m.modifySessionRecordingConfig(ctx, cfg, m.ClusterConfigurationInternal.CreateSessionRecordingConfig) + if err != nil { + return nil, trace.Wrap(err) + } + + return sessionRecordingConfig, trace.Wrap(err) +} + +// UpdateSessionRecordingConfig updates an existing session recording configuration. If encryption is enabled +// then an accessible encryption key pair will be confirmed. Either creating one if none exists, doing nothing +// if one is accessible, or returning an error if none are accessible. +func (m *Manager) UpdateSessionRecordingConfig(ctx context.Context, cfg types.SessionRecordingConfig) (types.SessionRecordingConfig, error) { + sessionRecordingConfig, err := m.modifySessionRecordingConfig(ctx, cfg, m.ClusterConfigurationInternal.UpdateSessionRecordingConfig) + if err != nil { + return nil, trace.Wrap(err) + } + + return sessionRecordingConfig, trace.Wrap(err) +} + +// UpsertSessionRecordingConfig creates a new session recording configuration or overwrites an existing one. If +// encryption is enabled then an accessible encryption key pair will be confirmed. Either creating one if none +// exists, doing nothing if one is accessible, or returning an error if none are accessible. +func (m *Manager) UpsertSessionRecordingConfig(ctx context.Context, cfg types.SessionRecordingConfig) (types.SessionRecordingConfig, error) { + sessionRecordingConfig, err := m.modifySessionRecordingConfig(ctx, cfg, m.ClusterConfigurationInternal.UpsertSessionRecordingConfig) + if err != nil { + return nil, trace.Wrap(err) + } + + return sessionRecordingConfig, trace.Wrap(err) +} + +// SetCache overwrites the configured Cache implementation. It should only be called if the `Manager` is not in use. +func (m *Manager) SetCache(cache Cache) { + m.cache = cache +} + +// fingerprintedDecrypter wraps a crypto.Decrypter with its public key fingerprint. +type fingerprintedDecrypter struct { + fingerprint string + decrypter crypto.Decrypter +} + +// ensureManualEncryptionKeys searches for accessible encryption keys in the configured key store using the key labels +// configured in the [ManualKeyManagementConfig] +func (m *Manager) ensureManualEncryptionKeys(ctx context.Context, manualKeyCfg types.ManualKeyManagementConfig) (*recordingencryptionv1.RecordingEncryption, error) { + m.manualKeyConfig = &manualKeyCfg + activeLabels := manualKeyCfg.ActiveKeys + rotatedLabels := manualKeyCfg.RotatedKeys + + // using the Manager's context here because we cache the resulting keys and want their lifetimes + // to be at least as long as the Manager + activeDecrypters, err := m.keyStore.FindDecryptersByLabels(ctx, activeLabels...) + if err != nil { + return nil, trace.Wrap(err) + } + + if len(activeDecrypters) == 0 { + return nil, trace.BadParameter("No accessible key found for manual_key_management.active_keys") + } + + rotatedDecrypters, err := m.keyStore.FindDecryptersByLabels(ctx, rotatedLabels...) + if err != nil { + return nil, trace.Wrap(err) + } + + if len(rotatedDecrypters) == 0 && len(rotatedLabels) > 0 { + // Failure to retrieve rotated keys should only prevent replay of historical recordings + // related to those keys, which isn't catastrophic in the way that missing active keys are. + // We should log the failure but otherwise press on. + m.logger.WarnContext(ctx, "No accessible rotated keys were found which may prevent replaying historical session recordings. Please ensure the Teleport Auth Service has access to the keystore and keys defined in manual_key_management.rotated_keys") + } + + var fingerprinted []fingerprintedDecrypter + for _, decrypter := range slices.Concat(rotatedDecrypters, activeDecrypters) { + fp, err := Fingerprint(decrypter.Public()) + if err != nil { + return nil, trace.Wrap(err) + } + + fingerprinted = append(fingerprinted, fingerprintedDecrypter{ + fingerprint: fp, + decrypter: decrypter, + }) + } + + m.keyCache.Write(func(cache map[string]crypto.Decrypter) { + for _, dec := range fingerprinted { + cache[dec.fingerprint] = dec.decrypter + } + }) + + var encryptionKeys []*recordingencryptionv1.KeyPair + for _, decrypter := range activeDecrypters { + pubKey, err := x509.MarshalPKIXPublicKey(decrypter.Public()) + if err != nil { + return nil, trace.Wrap(err) + } + + encryptionKeys = append(encryptionKeys, &recordingencryptionv1.KeyPair{ + KeyPair: &types.EncryptionKeyPair{ + PublicKey: pubKey, + }, + }) + } + return &recordingencryptionv1.RecordingEncryption{ + Spec: &recordingencryptionv1.RecordingEncryptionSpec{ + ActiveKeyPairs: encryptionKeys, + }, + }, nil +} + +// ensureActiveKeyPair checks that there is at least one accessible key in the list of active pairs given. +// If there are no active keys found, a new one will be provisioned and returned with the original set. +// An active but inaccessible key results in an error. +func (m *Manager) ensureActiveKeyPair(ctx context.Context, activePairs []*recordingencryptionv1.KeyPair) (newActivePairs []*recordingencryptionv1.KeyPair, keyGenerated bool, err error) { + var foundActiveKey bool + if len(activePairs) > 0 { + for _, pair := range activePairs { + if pair.State != recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE { + continue + } + + foundActiveKey = true + // fetch the decrypter to ensure we have access to it + if _, err := m.keyStore.GetDecrypter(ctx, pair.KeyPair); err != nil { + fp, _ := fingerprintPEM(pair.KeyPair.PublicKey) + m.logger.DebugContext(ctx, "key not accessible", "fingerprint", fp) + continue + } + return activePairs, false, nil + } + + // during a key rotation there may be no active keys which would mean reaching + // this point isn't an error + if foundActiveKey { + return nil, false, trace.AccessDenied("active key not accessible") + } + } + + // no active keys present, need to generate one + encryptionPair, err := m.keyStore.NewEncryptionKeyPair(ctx, cryptosuites.RecordingKeyWrapping) + if err != nil { + return nil, false, trace.Wrap(err, "generating wrapping key") + } + + fp, _ := fingerprintPEM(encryptionPair.PublicKey) + m.logger.InfoContext(ctx, "no active encryption keys, generated new pair", "public_fingerprint", fp) + + return append(activePairs, &recordingencryptionv1.KeyPair{ + KeyPair: encryptionPair, + State: recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, + }), true, nil +} + +// resolveRecordingEncryption returns the configured [RecordingEncryption] resource if it exists with an +// accessible key. If no active keys can be found and manual key management is disabled, a new key pair +// will be provisioned. An error is returned if an active key is found but is not accessible. It is also +// possible for the returned [RecordingEncryption] to be nil if the [SessionRecordingConfig] disables +// encryption altogether. +func (m *Manager) resolveRecordingEncryption(ctx context.Context, sessionRecordingCfg types.SessionRecordingConfig, encryption *recordingencryptionv1.RecordingEncryption) (*recordingencryptionv1.RecordingEncryption, error) { + // If encryption is disabled then we can skip resolving the RecordingEncryption. + if !sessionRecordingCfg.GetEncrypted() { + return encryption, nil + } + encryptionCfg := sessionRecordingCfg.GetEncryptionConfig() + manualKeyCfg := getManualKeyManagement(encryptionCfg) + if manualKeyCfg != nil { + encryption, err := m.ensureManualEncryptionKeys(ctx, *manualKeyCfg) + if err != nil { + return nil, trace.Wrap(err) + } + + return encryption, nil + } + + m.manualKeyConfig = nil + persistFn := m.RecordingEncryption.UpdateRecordingEncryption + forcePersist := encryption != nil + if encryption == nil { + var err error + encryption, err = m.RecordingEncryption.GetRecordingEncryption(ctx) + if err != nil { + if !trace.IsNotFound(err) { + return nil, trace.Wrap(err) + } + encryption = &recordingencryptionv1.RecordingEncryption{ + Spec: &recordingencryptionv1.RecordingEncryptionSpec{}, + } + persistFn = m.RecordingEncryption.CreateRecordingEncryption + } + } + + activePairs, keyGenerated, err := m.ensureActiveKeyPair(ctx, encryption.GetSpec().GetActiveKeyPairs()) + if err != nil { + return nil, trace.Wrap(err) + } + + if !forcePersist && !keyGenerated { + return encryption, nil + } + + encryption.Spec.ActiveKeyPairs = activePairs + encryption, err = persistFn(ctx, encryption) + if err != nil { + return nil, trace.Wrap(err) + } + return encryption, nil +} + +func (m *Manager) unwrapKeyUsingCache(in UnwrapInput) ([]byte, error) { + if decrypter, ok := m.keyCache.Load(in.Fingerprint); ok { + fileKey, err := decrypter.Decrypt(in.Rand, in.WrappedKey, in.Opts) + return fileKey, trace.Wrap(err) + } + + return nil, nil +} + +func (m *Manager) findDecrypter(ctx context.Context, fingerprint string) (crypto.Decrypter, error) { + encryption, err := m.cache.GetRecordingEncryption(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + activePairs := encryption.GetSpec().GetActiveKeyPairs() + for _, key := range activePairs { + if key.GetKeyPair() == nil { + continue + } + + activeFP, err := fingerprintPEM(key.KeyPair.PublicKey) + if err != nil { + m.logger.ErrorContext(ctx, "failed to fingerprint active public key", "error", err) + continue + } + + if activeFP != fingerprint { + continue + } + + decrypter, err := m.keyStore.GetDecrypter(ctx, key.KeyPair) + if err != nil { + continue + } + + return decrypter, nil + } + + // fallback to rotated keys if decrypter isn't found in active keys + rotatedKey, err := m.GetRotatedKey(ctx, fingerprint) + if err != nil { + return nil, trace.Wrap(err) + } + + decrypter, err := m.keyStore.GetDecrypter(ctx, rotatedKey.GetSpec().GetEncryptionKeyPair()) + if err != nil { + if trace.IsNotFound(err) { + return nil, trace.NotFound("no accessible decrypter found for fingerprint %q", fingerprint) + } + + return nil, trace.Wrap(err) + } + + return decrypter, nil +} + +// UnwrapKey searches for the private key compatible with the provided public key fingerprint and uses it to unwrap +// a wrapped file key. +func (m *Manager) UnwrapKey(ctx context.Context, in UnwrapInput) ([]byte, error) { + fileKey, err := m.unwrapKeyUsingCache(in) + if fileKey != nil && err == nil { + return fileKey, nil + } + + // a cache miss or unwrap failure for manually managed keys needs to attempt a refresh and try again + if m.manualKeyConfig != nil && m.manualKeyConfig.Enabled { + if _, err := m.ensureManualEncryptionKeys(ctx, *m.manualKeyConfig); err != nil { + return nil, trace.Wrap(err) + } + + fileKey, err = m.unwrapKeyUsingCache(in) + return fileKey, trace.Wrap(err) + } + + // a cache miss in for teleport managed keys just needs to fall back to the keystore + if err != nil { + m.logger.WarnContext(ctx, "failed to unwrap file key using cached decrypter, refetching from keystore") + } + + decrypter, err := m.findDecrypter(ctx, in.Fingerprint) + if err != nil { + return nil, trace.Wrap(err) + + } + + fileKey, err = decrypter.Decrypt(in.Rand, in.WrappedKey, in.Opts) + return fileKey, trace.Wrap(err) +} + +// RotateKey marks the currently active key pair as 'rotating' and adds a new pair to the active set. +func (m *Manager) RotateKey(ctx context.Context) error { + sessionRecordingConfig, err := m.GetSessionRecordingConfig(ctx) + if err != nil { + return trace.Wrap(err) + } + + if err := shouldManageKeys(sessionRecordingConfig); err != nil { + return trace.Wrap(err) + } + + encryption, err := m.GetRecordingEncryption(ctx) + if err != nil { + return trace.Wrap(err) + } + + activePairs := encryption.GetSpec().GetActiveKeyPairs() + var activePair *recordingencryptionv1.KeyPair + for _, pair := range activePairs { + switch pair.GetState() { + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING: + return trace.AlreadyExists("Recording encryption key rotation already in progress, complete or rollback to start a new one") + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_INACCESSIBLE: + return trace.BadParameter("Failed recording encryption key rotation in progress, at least one Teleport Auth Service does not have access to the new key pair. Please rollback the rotation, ensure that all Auth Services have access to provision and use keys within the configured keystore, and then try again.") + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE: + activePair = pair + } + } + + if activePair == nil { + return trace.NotFound("no active key present to rotate") + } + + activePair.State = recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING + if _, err := m.modifyRecordingEncryption(ctx, encryption); err != nil { + return trace.Wrap(err) + } + + return nil +} + +// CompleteRotation creates a new [RotatedKey] resource for rotating key pair and removes them from the active set. +func (m *Manager) CompleteRotation(ctx context.Context) error { + sessionRecordingConfig, err := m.GetSessionRecordingConfig(ctx) + if err != nil { + return trace.Wrap(err) + } + + if err := shouldManageKeys(sessionRecordingConfig); err != nil { + return trace.Wrap(err) + } + + encryption, err := m.GetRecordingEncryption(ctx) + if err != nil { + return trace.Wrap(err) + } + + activePairs := encryption.GetSpec().GetActiveKeyPairs() + var remainingPairs []*recordingencryptionv1.KeyPair + var rotatedPairs []*recordingencryptionv1.KeyPair + for _, pair := range activePairs { + switch pair.GetState() { + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING: + rotatedPairs = append(rotatedPairs, pair) + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE: + remainingPairs = append(remainingPairs, pair) + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_INACCESSIBLE: + return trace.BadParameter("Failed recording encryption key rotation in progress, at least one Teleport Auth Service does not have access to the new key pair. Please rollback the rotation, ensure that all Auth Services have access to provision and use keys within the configured keystore, and then try again.") + } + } + + for _, pair := range rotatedPairs { + if _, err := m.CreateRotatedKey(ctx, pair.GetKeyPair()); err != nil { + return trace.Wrap(err) + } + } + + encryption.Spec.ActiveKeyPairs = remainingPairs + if _, err := m.modifyRecordingEncryption(ctx, encryption); err != nil { + return trace.Wrap(err) + } + + return nil +} + +// RollbackRotation reverts an in progress rotation by setting 'rotating' keys back to 'active' and removing +// all other keys from the active set. +func (m *Manager) RollbackRotation(ctx context.Context) error { + sessionRecordingConfig, err := m.GetSessionRecordingConfig(ctx) + if err != nil { + return trace.Wrap(err) + } + + if err := shouldManageKeys(sessionRecordingConfig); err != nil { + return trace.Wrap(err) + } + + encryption, err := m.GetRecordingEncryption(ctx) + if err != nil { + return trace.Wrap(err) + } + + activePairs := encryption.GetSpec().GetActiveKeyPairs() + var rollbackPairs []*recordingencryptionv1.KeyPair + for _, pair := range activePairs { + if pair.GetState() == recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING { + pair.State = recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE + rollbackPairs = append(rollbackPairs, pair) + } + } + + if len(rollbackPairs) == 0 { + return trace.BadParameter("skipping rollback that would remove all encryption keys") + } + + encryption.Spec.ActiveKeyPairs = rollbackPairs + if _, err := m.modifyRecordingEncryption(ctx, encryption); err != nil { + return trace.Wrap(err) + } + + return nil +} + +// GetRotationState returns the state of each active key identified by a fingerprint. +func (m *Manager) GetRotationState(ctx context.Context) ([]*recordingencryptionv1.FingerprintWithState, error) { + sessionRecordingConfig, err := m.GetSessionRecordingConfig(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + if err := shouldManageKeys(sessionRecordingConfig); err != nil { + return nil, trace.Wrap(err) + } + + encryption, err := m.GetRecordingEncryption(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + activePairs := encryption.GetSpec().GetActiveKeyPairs() + if len(activePairs) == 0 { + return nil, nil + } + + states := make([]*recordingencryptionv1.FingerprintWithState, 0, len(activePairs)) + for _, pair := range activePairs { + fingerprint, err := fingerprintPEM(pair.GetKeyPair().PublicKey) + if err != nil { + return nil, trace.Wrap(err) + } + + states = append(states, &recordingencryptionv1.FingerprintWithState{ + Fingerprint: fingerprint, + State: pair.GetState(), + }) + } + + return states, nil +} + +// Watch for changes in the recording_encryption resource and respond by ensuring access to keys. +func (m *Manager) Watch(ctx context.Context, events types.Events) (err error) { + // shouldRetryAfterJitterFn waits at most 5 seconds and returns a bool specifying whether or not + // execution should continue + shouldRetryAfterJitterFn := func() bool { + select { + case <-time.After(retryutils.SeventhJitter(time.Second * 5)): + return true + case <-ctx.Done(): + return false + } + } + + // getNextManualSync returns a timed channel meant to trigger encryption key syncing when keys are + // manually managed + getNextManualSync := func() <-chan time.Time { + return time.After(retryutils.SeventhJitter(time.Minute * 5)) + } + + defer func() { + m.logger.InfoContext(ctx, "stopping encryption watcher", "error", err) + }() + + // on initial startup we should try to immediately resolve recording encryption + if err := m.resolveRecordingEncryptionState(ctx, shouldRetryAfterJitterFn); err != nil { + m.logger.ErrorContext(ctx, "initial attempt to resolve recording encryption failed", "error", err) + } + + nextSync := getNextManualSync() + for { + watch, err := events.NewWatcher(ctx, types.Watch{ + Name: "recording_encryption_watcher", + Kinds: []types.WatchKind{ + { + Kind: types.KindRecordingEncryption, + }, + }, + }) + if err != nil { + m.logger.ErrorContext(ctx, "failed to create watcher, retrying", "error", err) + if !shouldRetryAfterJitterFn() { + return nil + } + continue + } + defer watch.Close() + + HandleEvents: + for { + select { + case ev := <-watch.Events(): + if ev.Type != types.OpPut || ev.Resource.GetKind() != types.KindRecordingEncryption { + continue + } + if err := m.resolveRecordingEncryptionState(ctx, shouldRetryAfterJitterFn); err != nil { + m.logger.ErrorContext(ctx, "failure handling recording encryption event", "kind", ev.Resource.GetKind(), "error", err) + continue + } + // reset interval sync since we just resolved recording encryption state + nextSync = getNextManualSync() + case <-nextSync: + nextSync = getNextManualSync() + if m.manualKeyConfig == nil || !m.manualKeyConfig.Enabled { + // we only need to sync on an interval when keys are manually managed + continue + } + + if err := m.resolveRecordingEncryptionState(ctx, shouldRetryAfterJitterFn); err != nil { + m.logger.ErrorContext(ctx, "failed interval sync of recording encryption keys", "error", err) + } + case <-watch.Done(): + if err := watch.Error(); err == nil { + return nil + } + + m.logger.ErrorContext(ctx, "watcher failed, retrying", "error", err) + if !shouldRetryAfterJitterFn() { + return nil + } + break HandleEvents + case <-ctx.Done(): + return nil + } + + } + } +} + +// modifySessionRecordingConfig modifies the [SessionRecordingConfig] while maintaining the correct +// [RecordingEncryption] state. Any changes to active encryption keys are also applied to the [SessionRecordingConfig] +// before applying the change. +func (m *Manager) modifySessionRecordingConfig(ctx context.Context, cfg types.SessionRecordingConfig, persistFn func(context.Context, types.SessionRecordingConfig) (types.SessionRecordingConfig, error)) (types.SessionRecordingConfig, error) { + var result types.SessionRecordingConfig + err := backend.RunWhileLocked(ctx, m.lockConfig, func(ctx context.Context) error { + encryption, err := m.resolveRecordingEncryption(ctx, cfg, nil) + if err != nil { + return trace.Wrap(err) + } + + _ = cfg.SetEncryptionKeys(getAgeEncryptionKeys(encryption.GetSpec().GetActiveKeyPairs())) + result, err = persistFn(ctx, cfg) + return trace.Wrap(err) + }) + + return result, trace.Wrap(err) +} + +// modifyRecordingEncryption modifies the [RecordingEncryption] if the fetched [SessionRecordingConfig] allows it. +// Any changes to active encryption keys are also applied to the [SessionRecordingConfig] before releasing the lock. +func (m *Manager) modifyRecordingEncryption(ctx context.Context, encryption *recordingencryptionv1.RecordingEncryption) (*recordingencryptionv1.RecordingEncryption, error) { + var result *recordingencryptionv1.RecordingEncryption + err := backend.RunWhileLocked(ctx, m.lockConfig, func(ctx context.Context) error { + sessionRecordingCfg, err := m.GetSessionRecordingConfig(ctx) + if err != nil { + return trace.Wrap(err) + } + + result, err = m.resolveRecordingEncryption(ctx, sessionRecordingCfg, encryption) + if err != nil { + return trace.Wrap(err) + } + + if sessionRecordingCfg.SetEncryptionKeys(getAgeEncryptionKeys(result.GetSpec().GetActiveKeyPairs())) { + if _, err = m.ClusterConfigurationInternal.UpdateSessionRecordingConfig(ctx, sessionRecordingCfg); err != nil { + return trace.Wrap(err) + } + } + + return nil + }) + + return result, trace.Wrap(err) +} + +// resolveRecordingEncryptionState fetches the latest [SessionRecordingConfig] and [RecordingEncryption] resources +// from the backend and applies any updates the calling auth instance might require. This is meant to be run on an +// interval or in response to watch events. The primary updates expected are key state changes for inaccessible +// encryption keys and refreshing the manual key management cache. If the current state cannot be resolved after a +// number of retries, a [trace.LimitExceededError] is returned. +func (m *Manager) resolveRecordingEncryptionState(ctx context.Context, shouldRetryFn func() bool) error { + const retries = 3 + for retry := range retries { + if _, err := m.modifyRecordingEncryption(ctx, nil); err != nil { + m.logger.ErrorContext(ctx, "failed to resolve recording encryption keys, retrying", "retry", retry, "retries_left", retries-retry, "error", err) + if shouldRetryFn() { + continue + } + + return trace.Wrap(err) + } + + return nil + } + + return trace.LimitExceeded("resolving recording encryption exceeded max retries") +} + +// getAgeEncryptionKeys returns an iterator of AgeEncryptionKeys from a list of WrappedKeys. This is for use in +// populating the EncryptionKeys field of SessionRecordingConfigStatus. +func getAgeEncryptionKeys(keys []*recordingencryptionv1.KeyPair) iter.Seq[*types.AgeEncryptionKey] { + return func(yield func(*types.AgeEncryptionKey) bool) { + for _, key := range keys { + if key.KeyPair == nil { + continue + } + + if !yield(&types.AgeEncryptionKey{ + PublicKey: key.KeyPair.PublicKey, + }) { + return + } + } + } +} + +func getManualKeyManagement(encryptionCfg *types.SessionRecordingEncryptionConfig) *types.ManualKeyManagementConfig { + if encryptionCfg == nil { + return nil + } + + if encryptionCfg.ManualKeyManagement == nil || !encryptionCfg.ManualKeyManagement.Enabled { + return nil + } + + return encryptionCfg.ManualKeyManagement +} + +func shouldManageKeys(sessionRecordingConfig types.SessionRecordingConfig) error { + encryptionCfg := sessionRecordingConfig.GetEncryptionConfig() + if encryptionCfg == nil || !encryptionCfg.Enabled { + return trace.NotFound("session recording encryption is not enabled") + } + + if manual := getManualKeyManagement(encryptionCfg); manual != nil && manual.Enabled { + return trace.NotFound("session recording encryption is using manual key management") + } + + return nil +} + +// Fingerprint a public key for use in logging and as a cache key. +func Fingerprint(pubKey crypto.PublicKey) (string, error) { + derPub, err := x509.MarshalPKIXPublicKey(pubKey) + if err != nil { + return "", trace.Wrap(err) + } + + fp := sha256.Sum256(derPub) + return hex.EncodeToString(fp[:]), nil +} + +// fingerprints a public RSA key encoded as PEM-wrapped PKIX. +func fingerprintPEM(pubKeyPEM []byte) (string, error) { + pubKey, err := x509.ParsePKIXPublicKey(pubKeyPEM) + if err != nil { + return "", trace.Wrap(err) + } + + return Fingerprint(pubKey) +} diff --git a/lib/auth/recordingencryption/manager_test.go b/lib/auth/recordingencryption/manager_test.go new file mode 100644 index 0000000000000..98f1a3ee8fc5e --- /dev/null +++ b/lib/auth/recordingencryption/manager_test.go @@ -0,0 +1,655 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package recordingencryption_test + +import ( + "context" + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "errors" + "io" + "os" + "slices" + "sync" + "testing" + "time" + + "github.com/gravitational/trace" + "github.com/jonboulle/clockwork" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth/recordingencryption" + "github.com/gravitational/teleport/lib/backend" + "github.com/gravitational/teleport/lib/backend/memory" + "github.com/gravitational/teleport/lib/cryptosuites" + "github.com/gravitational/teleport/lib/cryptosuites/cryptosuitestest" + "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/teleport/lib/services/local" + "github.com/gravitational/teleport/lib/utils/log/logtest" +) + +func TestMain(m *testing.M) { + ctx, cancel := context.WithCancel(context.Background()) + cryptosuitestest.PrecomputeRSAKeys(ctx) + exitCode := m.Run() + cancel() + os.Exit(exitCode) +} + +type oaepDecrypter struct { + crypto.Decrypter + hash crypto.Hash +} + +func (d oaepDecrypter) Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) ([]byte, error) { + return d.Decrypter.Decrypt(rand, msg, opts) +} + +type fakeKeyStore struct { + keyType types.PrivateKeyType // abusing this field as a way to simulate different auth servers + keys map[string][]crypto.Decrypter + currLabel types.KeyLabel +} + +func newFakeKeyStore(keyType types.PrivateKeyType) *fakeKeyStore { + return &fakeKeyStore{ + keys: make(map[string][]crypto.Decrypter), + keyType: keyType, + currLabel: types.KeyLabel{ + Type: "pkcs11", + Label: "test", + }, + } +} + +func (f *fakeKeyStore) genKeys() (crypto.Decrypter, []byte, error) { + signer, err := cryptosuites.GenerateKeyWithAlgorithm(cryptosuites.RSA4096) + if err != nil { + return nil, nil, err + } + + private, ok := signer.(*rsa.PrivateKey) + if !ok { + return nil, nil, trace.Errorf("expected RSA key") + } + + publicKey, err := x509.MarshalPKIXPublicKey(&private.PublicKey) + if err != nil { + return nil, nil, err + } + + return private, publicKey, nil +} + +func (f *fakeKeyStore) createKey() (crypto.Decrypter, []byte, error) { + decrypter, publicKey, err := f.genKeys() + if err != nil { + return nil, nil, err + } + + fp, err := recordingencryption.Fingerprint(decrypter.Public()) + if err != nil { + return nil, nil, err + } + + if f.keys == nil { + f.keys = make(map[string][]crypto.Decrypter) + } + + f.keys[fp] = []crypto.Decrypter{decrypter} + + return decrypter, publicKey, nil +} + +func (f *fakeKeyStore) NewEncryptionKeyPair(ctx context.Context, purpose cryptosuites.KeyPurpose) (*types.EncryptionKeyPair, error) { + decrypter, pubDER, err := f.createKey() + if err != nil { + return nil, err + } + + private, ok := decrypter.(*rsa.PrivateKey) + if !ok { + return nil, errors.New("expected RSA private key") + } + + privateDER, err := x509.MarshalPKCS8PrivateKey(private) + if err != nil { + return nil, err + } + + label := f.currLabel.Type + ":" + f.currLabel.Label + f.keys[label] = append(f.keys[label], private) + + return &types.EncryptionKeyPair{ + PrivateKey: privateDER, + PublicKey: pubDER, + PrivateKeyType: f.keyType, + Hash: uint32(crypto.SHA256), + }, nil +} + +func (f *fakeKeyStore) GetDecrypter(ctx context.Context, keyPair *types.EncryptionKeyPair) (crypto.Decrypter, error) { + if keyPair.PrivateKeyType != f.keyType { + return nil, errors.New("could not access decrypter") + } + + private, err := x509.ParsePKCS8PrivateKey(keyPair.PrivateKey) + if err != nil { + return nil, err + } + + decrypter, ok := private.(crypto.Decrypter) + if !ok { + return nil, errors.New("private key should have been a decrypter") + } + return oaepDecrypter{Decrypter: decrypter, hash: crypto.Hash(keyPair.Hash)}, nil +} + +func (f *fakeKeyStore) UnwrapKey(ctx context.Context, in recordingencryption.UnwrapInput) ([]byte, error) { + decrypter, ok := f.keys[in.Fingerprint] + if !ok { + return nil, trace.NotFound("no accessible decryption key found") + } + + fileKey, err := decrypter[0].Decrypt(in.Rand, in.WrappedKey, in.Opts) + if err != nil { + return nil, err + } + + return fileKey, nil +} + +func (f *fakeKeyStore) FindDecryptersByLabels(ctx context.Context, labels ...*types.KeyLabel) ([]crypto.Decrypter, error) { + var decrypters []crypto.Decrypter + for _, label := range labels { + lookup := label.Type + ":" + label.Label + decrypters = append(decrypters, f.keys[lookup]...) + } + + return decrypters, nil +} + +func newLocalBackend( + t *testing.T, +) (context.Context, backend.Backend) { + t.Parallel() + ctx := t.Context() + clock := clockwork.NewRealClock() + mem, err := memory.New(memory.Config{ + Context: ctx, + Clock: clock, + }) + require.NoError(t, err) + bk := backend.NewSanitizer(mem) + return ctx, bk +} + +func newManagerConfig(t *testing.T, bk backend.Backend, keyType types.PrivateKeyType) recordingencryption.ManagerConfig { + recordingEncryptionService, err := local.NewRecordingEncryptionService(bk) + require.NoError(t, err) + + clusterConfigService, err := local.NewClusterConfigurationService(bk) + require.NoError(t, err) + + src := &types.SessionRecordingConfigV2{} + require.NoError(t, src.CheckAndSetDefaults()) + src.Spec.Encryption = &types.SessionRecordingEncryptionConfig{ + Enabled: true, + } + + return recordingencryption.ManagerConfig{ + Backend: recordingEncryptionService, + Cache: recordingEncryptionService, + ClusterConfig: clusterConfigService, + KeyStore: newFakeKeyStore(keyType), + Logger: logtest.NewLogger(), + LockConfig: backend.RunWhileLockedConfig{ + LockConfiguration: backend.LockConfiguration{ + Backend: bk, + LockNameComponents: []string{"recording_encryption"}, + TTL: 10 * time.Second, + RetryInterval: 100 * time.Millisecond, + }, + }, + } +} + +// resolve is a proxy to Manager.resolveRecordingEncryption through calling UpsertSessionRecordingConfig +func resolve(ctx context.Context, service services.RecordingEncryption, manager *recordingencryption.Manager) (*recordingencryptionv1.RecordingEncryption, types.SessionRecordingConfig, error) { + req := types.SessionRecordingConfigV2{ + Spec: types.SessionRecordingConfigSpecV2{ + Encryption: &types.SessionRecordingEncryptionConfig{ + Enabled: true, + }, + }, + } + if err := req.CheckAndSetDefaults(); err != nil { + return nil, nil, trace.Wrap(err) + } + + src, err := manager.UpsertSessionRecordingConfig(ctx, &req) + if err != nil { + return nil, nil, trace.Wrap(err) + } + + encryption, err := service.GetRecordingEncryption(ctx) + if err != nil { + return nil, nil, trace.Wrap(err) + } + + return encryption, src, nil +} + +func TestCreateUpdateSessionRecordingConfig(t *testing.T) { + ctx, bk := newLocalBackend(t) + + config := newManagerConfig(t, bk, types.PrivateKeyType_RAW) + manager, err := recordingencryption.NewManager(ctx, config) + require.NoError(t, err) + + req := &types.SessionRecordingConfigV2{} + require.NoError(t, req.CheckAndSetDefaults()) + req.Spec.Encryption = &types.SessionRecordingEncryptionConfig{ + Enabled: true, + } + + // create should provision initial keypair and write public key to SRC + src, err := manager.CreateSessionRecordingConfig(ctx, req) + require.NoError(t, err) + encryptionKeys := src.GetEncryptionKeys() + require.Len(t, encryptionKeys, 1) + + encryption, err := config.Backend.GetRecordingEncryption(ctx) + require.NoError(t, err) + activePairs := encryption.GetSpec().GetActiveKeyPairs() + require.Len(t, activePairs, 1) + require.NotNil(t, activePairs[0].KeyPair) + require.NotEmpty(t, activePairs[0].KeyPair.PrivateKey) + require.NotEmpty(t, activePairs[0].KeyPair.PublicKey) + + // update should change nothing + src, err = manager.UpdateSessionRecordingConfig(ctx, src) + require.NoError(t, err) + newEncryptionKeys := src.GetEncryptionKeys() + require.ElementsMatch(t, newEncryptionKeys, encryptionKeys) + + encryption, err = config.Backend.GetRecordingEncryption(ctx) + require.NoError(t, err) + newActiveKeyPairs := encryption.GetSpec().GetActiveKeyPairs() + require.ElementsMatch(t, newActiveKeyPairs, activePairs) +} + +func TestResolveRecordingEncryption(t *testing.T) { + // SETUP + ctx, bk := newLocalBackend(t) + + managerABType := types.PrivateKeyType_AWS_KMS + managerCType := types.PrivateKeyType_GCP_KMS + + configA := newManagerConfig(t, bk, managerABType) + configB := configA + configC := configA + configC.KeyStore = newFakeKeyStore(managerCType) + + managerA, err := recordingencryption.NewManager(ctx, configA) + require.NoError(t, err) + + managerB, err := recordingencryption.NewManager(ctx, configB) + require.NoError(t, err) + + managerC, err := recordingencryption.NewManager(ctx, configC) + require.NoError(t, err) + + service := configA.Backend + + // TEST + // CASE: service A first evaluation initializes recording encryption resource + encryption, src, err := resolve(ctx, service, managerA) + require.NoError(t, err) + initialKeys := encryption.GetSpec().GetActiveKeyPairs() + + require.Len(t, initialKeys, 1) + require.Len(t, src.GetEncryptionKeys(), 1) + key := initialKeys[0] + require.Equal(t, key.KeyPair.PublicKey, src.GetEncryptionKeys()[0].PublicKey) + require.NotNil(t, key.KeyPair) + + // CASE: service B should have access to the same key + encryption, src, err = resolve(ctx, service, managerB) + require.NoError(t, err) + + activePairs := encryption.GetSpec().ActiveKeyPairs + require.Len(t, src.GetEncryptionKeys(), 1) + require.Equal(t, key.KeyPair.PublicKey, src.GetEncryptionKeys()[0].PublicKey) + require.ElementsMatch(t, initialKeys, activePairs) + + // service C should error without access to the current key + _, _, err = resolve(ctx, service, managerC) + require.Error(t, err) +} + +func TestResolveRecordingEncryptionConcurrent(t *testing.T) { + // SETUP + ctx, bk := newLocalBackend(t) + + config := newManagerConfig(t, bk, types.PrivateKeyType_RAW) + managerA, err := recordingencryption.NewManager(ctx, config) + require.NoError(t, err) + + managerB, err := recordingencryption.NewManager(ctx, config) + require.NoError(t, err) + + serviceC, err := recordingencryption.NewManager(ctx, config) + require.NoError(t, err) + + service := config.Backend + resolveFn := func(manager *recordingencryption.Manager, wg *sync.WaitGroup) { + wg.Add(1) + go func() { + defer wg.Done() + resolve(ctx, service, manager) + require.NoError(t, err) + }() + } + + // it should be safe for multiple services to resolve encryption keys concurrently + wg := sync.WaitGroup{} + resolveFn(managerA, &wg) + resolveFn(managerB, &wg) + resolveFn(serviceC, &wg) + wg.Wait() + + encryption, err := service.GetRecordingEncryption(ctx) + require.NoError(t, err) + + activePairs := encryption.GetSpec().ActiveKeyPairs + // each service should share a single active key + require.Len(t, activePairs, 1) + require.NotNil(t, activePairs[0].KeyPair) + require.NotEmpty(t, activePairs[0].KeyPair.PrivateKey) + require.NotEmpty(t, activePairs[0].KeyPair.PublicKey) + require.Equal(t, types.PrivateKeyType_RAW, activePairs[0].KeyPair.PrivateKeyType) +} + +func TestUnwrapKey(t *testing.T) { + // SETUP + ctx, bk := newLocalBackend(t) + keyType := types.PrivateKeyType_RAW + + config := newManagerConfig(t, bk, keyType) + manager, err := recordingencryption.NewManager(ctx, config) + require.NoError(t, err) + + service := config.Backend + _, _, err = resolve(ctx, service, manager) + require.NoError(t, err) + + src, err := manager.GetSessionRecordingConfig(ctx) + require.NoError(t, err) + + encryptionKeys := src.GetEncryptionKeys() + require.Len(t, encryptionKeys, 1) + pubKeyDER := encryptionKeys[0].PublicKey + + pubKey, err := x509.ParsePKIXPublicKey(pubKeyDER) + require.NoError(t, err) + + rsaPubKey, ok := pubKey.(*rsa.PublicKey) + require.True(t, ok) + + fileKey := []byte("test_file_key") + label := []byte("test_label") + wrappedKey, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, rsaPubKey, fileKey, label) + require.NoError(t, err) + + fp, err := recordingencryption.Fingerprint(pubKey) + require.NoError(t, err) + + unwrapInput := recordingencryption.UnwrapInput{ + Fingerprint: fp, + WrappedKey: wrappedKey, + Rand: rand.Reader, + Opts: &rsa.OAEPOptions{ + Hash: crypto.SHA256, + Label: label, + }, + } + unwrappedKey, err := manager.UnwrapKey(ctx, unwrapInput) + require.NoError(t, err) + + require.Equal(t, fileKey, unwrappedKey) +} + +func TestRotateKey(t *testing.T) { + ctx, bk := newLocalBackend(t) + + config := newManagerConfig(t, bk, types.PrivateKeyType_RAW) + manager, err := recordingencryption.NewManager(ctx, config) + require.NoError(t, err) + + req := &types.SessionRecordingConfigV2{} + require.NoError(t, req.CheckAndSetDefaults()) + req.Spec.Encryption = &types.SessionRecordingEncryptionConfig{ + Enabled: true, + } + + // setup initial state + src, err := manager.CreateSessionRecordingConfig(ctx, req) + require.NoError(t, err) + encryptionKeys := src.GetEncryptionKeys() + require.Len(t, encryptionKeys, 1) + + encryption, err := config.Backend.GetRecordingEncryption(ctx) + require.NoError(t, err) + activePairs := encryption.GetSpec().GetActiveKeyPairs() + require.Len(t, activePairs, 1) + initialKey := activePairs[0] + require.NotNil(t, initialKey.KeyPair) + require.NotEmpty(t, initialKey.KeyPair.PrivateKey) + require.NotEmpty(t, initialKey.KeyPair.PublicKey) + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, initialKey.State) + + // rotate key + err = manager.RotateKey(ctx) + require.NoError(t, err) + + encryption, err = config.Backend.GetRecordingEncryption(ctx) + require.NoError(t, err) + activePairs = encryption.GetSpec().GetActiveKeyPairs() + require.Len(t, activePairs, 2) + + var foundInitialPair bool + var newPair *recordingencryptionv1.KeyPair + for _, pair := range activePairs { + if slices.Equal(initialKey.KeyPair.PublicKey, pair.KeyPair.PublicKey) { + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING, pair.State) + foundInitialPair = true + } else { + newPair = pair + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, pair.State) + } + } + + require.True(t, foundInitialPair && newPair != nil) + + // complete rotation + err = manager.CompleteRotation(ctx) + require.NoError(t, err) + + encryption, err = config.Backend.GetRecordingEncryption(ctx) + require.NoError(t, err) + activePairs = encryption.GetSpec().GetActiveKeyPairs() + require.Len(t, activePairs, 1) + + require.Equal(t, newPair.KeyPair.PublicKey, activePairs[0].KeyPair.PublicKey) + require.Equal(t, newPair.KeyPair.PrivateKey, activePairs[0].KeyPair.PrivateKey) + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, activePairs[0].State) + + pubKey, err := x509.ParsePKIXPublicKey(initialKey.KeyPair.PublicKey) + require.NoError(t, err) + + fingerprint, err := recordingencryption.Fingerprint(pubKey) + require.NoError(t, err) + + rotatedKey, err := config.Backend.GetRotatedKey(ctx, fingerprint) + require.NoError(t, err) + + require.Equal(t, initialKey.KeyPair.PublicKey, rotatedKey.Spec.EncryptionKeyPair.PublicKey) + require.Equal(t, initialKey.KeyPair.PrivateKey, rotatedKey.Spec.EncryptionKeyPair.PrivateKey) +} + +func TestRotateRollback(t *testing.T) { + ctx, bk := newLocalBackend(t) + + config := newManagerConfig(t, bk, types.PrivateKeyType_RAW) + manager, err := recordingencryption.NewManager(ctx, config) + require.NoError(t, err) + + req := &types.SessionRecordingConfigV2{} + require.NoError(t, req.CheckAndSetDefaults()) + req.Spec.Encryption = &types.SessionRecordingEncryptionConfig{ + Enabled: true, + } + + // setup initial state + src, err := manager.CreateSessionRecordingConfig(ctx, req) + require.NoError(t, err) + encryptionKeys := src.GetEncryptionKeys() + require.Len(t, encryptionKeys, 1) + + encryption, err := config.Backend.GetRecordingEncryption(ctx) + require.NoError(t, err) + activePairs := encryption.GetSpec().GetActiveKeyPairs() + require.Len(t, activePairs, 1) + initialKey := proto.CloneOf(activePairs[0]) + require.NotNil(t, initialKey.KeyPair) + require.NotEmpty(t, initialKey.KeyPair.PrivateKey) + require.NotEmpty(t, initialKey.KeyPair.PublicKey) + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, initialKey.State) + + // rotate key + err = manager.RotateKey(ctx) + require.NoError(t, err) + + encryption, err = config.Backend.GetRecordingEncryption(ctx) + require.NoError(t, err) + activePairs = encryption.GetSpec().GetActiveKeyPairs() + require.Len(t, activePairs, 2) + + var foundInitialPair bool + var newPair *recordingencryptionv1.KeyPair + for _, pair := range activePairs { + if slices.Equal(initialKey.KeyPair.PublicKey, pair.KeyPair.PublicKey) { + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING, pair.State) + foundInitialPair = true + } else { + newPair = pair + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, pair.State) + } + } + + require.True(t, foundInitialPair && newPair != nil) + + // rollback rotation + err = manager.RollbackRotation(ctx) + require.NoError(t, err) + + encryption, err = config.Backend.GetRecordingEncryption(ctx) + require.NoError(t, err) + activePairs = encryption.GetSpec().GetActiveKeyPairs() + require.Len(t, activePairs, 1) + + require.Equal(t, initialKey.KeyPair.PublicKey, activePairs[0].KeyPair.PublicKey) + require.Equal(t, initialKey.KeyPair.PrivateKey, activePairs[0].KeyPair.PrivateKey) + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, activePairs[0].State) + + pubKey, err := x509.ParsePKIXPublicKey(initialKey.KeyPair.PublicKey) + require.NoError(t, err) + + fingerprint, err := recordingencryption.Fingerprint(pubKey) + require.NoError(t, err) + + // no rotated key should be found after a rollback + _, err = config.Backend.GetRotatedKey(ctx, fingerprint) + require.Error(t, err) +} + +func TestRotateKeyDisabled(t *testing.T) { + ctx, bk := newLocalBackend(t) + + config := newManagerConfig(t, bk, types.PrivateKeyType_RAW) + manager, err := recordingencryption.NewManager(ctx, config) + require.NoError(t, err) + + req := &types.SessionRecordingConfigV2{} + require.NoError(t, req.CheckAndSetDefaults()) + req.Spec.Encryption = &types.SessionRecordingEncryptionConfig{ + Enabled: false, + } + + // setup initial state + src, err := manager.CreateSessionRecordingConfig(ctx, req) + require.NoError(t, err) + + err = manager.RotateKey(ctx) + require.True(t, trace.IsNotFound(err)) + + _, err = manager.GetRotationState(ctx) + require.True(t, trace.IsNotFound(err)) + + err = manager.CompleteRotation(ctx) + require.True(t, trace.IsNotFound(err)) + + err = manager.RollbackRotation(ctx) + require.True(t, trace.IsNotFound(err)) + + _, err = config.KeyStore.NewEncryptionKeyPair(ctx, cryptosuites.RecordingKeyWrapping) + require.NoError(t, err) + + cfg, ok := src.(*types.SessionRecordingConfigV2) + require.True(t, ok, "expected SessionRecordingConfigV2") + + cfg.Spec.Encryption.Enabled = true + cfg.Spec.Encryption.ManualKeyManagement = &types.ManualKeyManagementConfig{ + Enabled: true, + ActiveKeys: []*types.KeyLabel{{ + Type: "pkcs11", + Label: "test", + }}, + } + + _, err = manager.UpdateSessionRecordingConfig(ctx, req) + require.NoError(t, err) + + err = manager.RotateKey(ctx) + require.True(t, trace.IsNotFound(err)) + + _, err = manager.GetRotationState(ctx) + require.True(t, trace.IsNotFound(err)) + + err = manager.CompleteRotation(ctx) + require.True(t, trace.IsNotFound(err)) + + err = manager.RollbackRotation(ctx) + require.True(t, trace.IsNotFound(err)) +} diff --git a/lib/auth/recordingencryption/recordingencryptionv1/service.go b/lib/auth/recordingencryption/recordingencryptionv1/service.go new file mode 100644 index 0000000000000..9cf6fa6235553 --- /dev/null +++ b/lib/auth/recordingencryption/recordingencryptionv1/service.go @@ -0,0 +1,267 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package recordingencryptionv1 + +import ( + "bytes" + "context" + "log/slog" + "time" + + "github.com/gravitational/trace" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/gravitational/teleport" + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/lib/authz" + "github.com/gravitational/teleport/lib/events" + "github.com/gravitational/teleport/lib/session" +) + +// A KeyRotater facilitates rotation of encryption keys. +type KeyRotater interface { + RotateKey(context.Context) error + CompleteRotation(context.Context) error + RollbackRotation(context.Context) error + GetRotationState(context.Context) ([]*recordingencryptionv1.FingerprintWithState, error) +} + +// ServiceConfig captures everything a [Service] requires to fulfill requests. +type ServiceConfig struct { + Authorizer authz.Authorizer + Logger *slog.Logger + Uploader events.MultipartUploader + KeyRotater KeyRotater +} + +// NewService returns a new [Service] based on the given [ServiceConfig]. +func NewService(cfg ServiceConfig) (*Service, error) { + switch { + case cfg.Authorizer == nil: + return nil, trace.BadParameter("authorizer is required") + case cfg.Uploader == nil: + return nil, trace.BadParameter("uploader is required") + case cfg.KeyRotater == nil: + return nil, trace.BadParameter("key rotater is required") + } + + if cfg.Logger == nil { + cfg.Logger = slog.With(teleport.ComponentKey, teleport.ComponentRecordingEncryption) + } + + return &Service{ + logger: cfg.Logger, + uploader: cfg.Uploader, + auth: cfg.Authorizer, + rotater: cfg.KeyRotater, + }, nil +} + +// Service implements a gRPC server for interacting with encrypted recordings. +type Service struct { + recordingencryptionv1.UnimplementedRecordingEncryptionServiceServer + + auth authz.Authorizer + logger *slog.Logger + uploader events.MultipartUploader + rotater KeyRotater +} + +func streamUploadAsProto(upload events.StreamUpload) *recordingencryptionv1.Upload { + return &recordingencryptionv1.Upload{ + UploadId: upload.ID, + SessionId: upload.SessionID.String(), + InitiatedAt: timestamppb.New(upload.Initiated), + } +} + +func protoAsStreamUpload(upload *recordingencryptionv1.Upload) (events.StreamUpload, error) { + sessionID, err := session.ParseID(upload.SessionId) + if err != nil { + return events.StreamUpload{}, trace.Wrap(err) + } + + return events.StreamUpload{ + ID: upload.UploadId, + SessionID: *sessionID, + Initiated: upload.InitiatedAt.AsTime(), + }, nil +} + +func protoAsStreamPart(part *recordingencryptionv1.Part) events.StreamPart { + return events.StreamPart{ + Number: part.PartNumber, + ETag: part.Etag, + LastModified: time.Now(), + } +} + +// CreateUpload begins a multipart upload for an encrypted session recording. +func (s *Service) CreateUpload(ctx context.Context, req *recordingencryptionv1.CreateUploadRequest) (*recordingencryptionv1.CreateUploadResponse, error) { + authCtx, err := s.auth.Authorize(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + if !authz.IsLocalOrRemoteService(*authCtx) { + return nil, trace.AccessDenied("this request can be only executed by a Teleport service") + } + + s.logger.DebugContext(ctx, "creating encrypted session upload", "session_id", req.SessionId) + sessionID, err := session.ParseID(req.SessionId) + if err != nil { + return nil, trace.Wrap(err) + } + + upload, err := s.uploader.CreateUpload(ctx, *sessionID) + if err != nil { + return nil, trace.Wrap(err, "creating encrypted recording upload") + } + + return &recordingencryptionv1.CreateUploadResponse{ + Upload: streamUploadAsProto(*upload), + }, nil +} + +// UploadPart uploads an encrypted session recording part to the given upload ID. +func (s *Service) UploadPart(ctx context.Context, req *recordingencryptionv1.UploadPartRequest) (*recordingencryptionv1.UploadPartResponse, error) { + authCtx, err := s.auth.Authorize(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + if !authz.IsLocalOrRemoteService(*authCtx) { + return nil, trace.AccessDenied("this request can be only executed by a Teleport service") + } + + s.logger.DebugContext(ctx, "uploading encrypted session part", "upload_id", req.Upload.UploadId, "session_id", req.Upload.SessionId, "part_number", req.PartNumber) + upload, err := protoAsStreamUpload(req.Upload) + if err != nil { + return nil, trace.Wrap(err) + } + + if err := s.uploader.ReserveUploadPart(ctx, upload, req.PartNumber); err != nil { + return nil, trace.Wrap(err) + } + + part := bytes.NewReader(req.Part) + streamPart, err := s.uploader.UploadPart(ctx, upload, req.PartNumber, part) + if err != nil { + return nil, trace.Wrap(err, "uploading encrypted recording part") + } + + return &recordingencryptionv1.UploadPartResponse{ + Part: &recordingencryptionv1.Part{ + PartNumber: streamPart.Number, + Etag: streamPart.ETag, + }, + }, nil +} + +// CompleteUpload marks a given encrypted session upload as complete. +func (s *Service) CompleteUpload(ctx context.Context, req *recordingencryptionv1.CompleteUploadRequest) (*recordingencryptionv1.CompleteUploadResponse, error) { + authCtx, err := s.auth.Authorize(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + if !authz.IsLocalOrRemoteService(*authCtx) { + return nil, trace.AccessDenied("this request can be only executed by a Teleport service") + } + + s.logger.DebugContext(ctx, "completing encrypted session upload", "upload_id", req.Upload.UploadId, "session_id", req.Upload.SessionId, "parts", len(req.Parts)) + upload, err := protoAsStreamUpload(req.Upload) + if err != nil { + return nil, trace.Wrap(err) + } + + parts := make([]events.StreamPart, len(req.Parts)) + for idx, part := range req.Parts { + parts[idx] = protoAsStreamPart(part) + } + + if err := s.uploader.CompleteUpload(ctx, upload, parts); err != nil { + return nil, trace.Wrap(err) + } + + return &recordingencryptionv1.CompleteUploadResponse{}, nil +} + +func (s *Service) authorizeKeyRotation(ctx context.Context) error { + authCtx, err := s.auth.Authorize(ctx) + if err != nil { + return trace.Wrap(err) + } + + if err := authCtx.AuthorizeAdminAction(); err != nil { + return trace.AccessDenied("Key rotation can only be performed by admins") + } + + return nil +} + +// RotateKey starts the rotation process for the active key pair used while encrypting session recording data. +func (s *Service) RotateKey(ctx context.Context, req *recordingencryptionv1.RotateKeyRequest) (*recordingencryptionv1.RotateKeyResponse, error) { + if err := s.authorizeKeyRotation(ctx); err != nil { + return nil, trace.Wrap(err) + } + + if err := s.rotater.RotateKey(ctx); err != nil { + return nil, trace.Wrap(err) + } + + return &recordingencryptionv1.RotateKeyResponse{}, nil +} + +// CompleteRotation moves rotated keys out of the active set into new RotatedKey resources. +func (s *Service) CompleteRotation(ctx context.Context, req *recordingencryptionv1.CompleteRotationRequest) (*recordingencryptionv1.CompleteRotationResponse, error) { + if err := s.authorizeKeyRotation(ctx); err != nil { + return nil, trace.Wrap(err) + } + + if err := s.rotater.CompleteRotation(ctx); err != nil { + return nil, trace.Wrap(err) + } + + return &recordingencryptionv1.CompleteRotationResponse{}, nil +} + +// RollbackRotation removes active keys and reverts rotating keys back to being active. +func (s *Service) RollbackRotation(ctx context.Context, req *recordingencryptionv1.RollbackRotationRequest) (*recordingencryptionv1.RollbackRotationResponse, error) { + if err := s.authorizeKeyRotation(ctx); err != nil { + return nil, trace.Wrap(err) + } + + if err := s.rotater.RollbackRotation(ctx); err != nil { + return nil, trace.Wrap(err) + } + + return &recordingencryptionv1.RollbackRotationResponse{}, nil +} + +// GetRotationState the state and fingerprint of all currently active keys. +func (s *Service) GetRotationState(ctx context.Context, req *recordingencryptionv1.GetRotationStateRequest) (*recordingencryptionv1.GetRotationStateResponse, error) { + if err := s.authorizeKeyRotation(ctx); err != nil { + return nil, trace.Wrap(err) + } + + states, err := s.rotater.GetRotationState(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + return &recordingencryptionv1.GetRotationStateResponse{ + KeyPairStates: states, + }, nil +} diff --git a/lib/auth/recordingencryption/recordingencryptionv1/service_test.go b/lib/auth/recordingencryption/recordingencryptionv1/service_test.go new file mode 100644 index 0000000000000..e233fb40f0cdf --- /dev/null +++ b/lib/auth/recordingencryption/recordingencryptionv1/service_test.go @@ -0,0 +1,302 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package recordingencryptionv1_test + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/google/uuid" + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" + + recordingencryptionv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/lib/auth/recordingencryption/recordingencryptionv1" + "github.com/gravitational/teleport/lib/authz" + "github.com/gravitational/teleport/lib/events" + "github.com/gravitational/teleport/lib/utils/log/logtest" +) + +type authKey struct{} + +func withAuthCtx(ctx context.Context, authCtx authz.Context) context.Context { + return context.WithValue(ctx, authKey{}, authCtx) +} + +func TestRotateKey(t *testing.T) { + cases := []struct { + name string + ctx authz.Context + expectErr bool + }{ + { + name: "authorized RotateKey", + ctx: newAuthCtx(authz.AdminActionAuthMFAVerified), + }, { + name: "unauthorized RotateKey", + ctx: newAuthCtx(authz.AdminActionAuthUnauthorized), + expectErr: true, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + ctx := withAuthCtx(t.Context(), c.ctx) + rotater := newFakeKeyRotater() + cfg := recordingencryptionv1.ServiceConfig{ + Authorizer: &fakeAuthorizer{}, + Logger: logtest.NewLogger(), + Uploader: fakeUploader{}, + KeyRotater: rotater, + } + + service, err := recordingencryptionv1.NewService(cfg) + require.NoError(t, err) + require.Len(t, rotater.keys, 1) + + _, err = service.RotateKey(ctx, nil) + if c.expectErr { + require.True(t, trace.IsAccessDenied(err)) + require.Len(t, rotater.keys, 1) + } else { + require.NoError(t, err) + require.Len(t, rotater.keys, 2) + } + + }) + } +} + +func TestCompleteRotation(t *testing.T) { + cases := []struct { + name string + ctx authz.Context + expectErr bool + }{ + { + name: "authorized CompleteRotation", + ctx: newAuthCtx(authz.AdminActionAuthMFAVerified), + }, { + name: "unauthorized CompleteRotation", + ctx: newAuthCtx(authz.AdminActionAuthUnauthorized), + expectErr: true, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + authCtx := withAuthCtx(t.Context(), newAuthCtx(authz.AdminActionAuthMFAVerified)) + ctx := withAuthCtx(t.Context(), c.ctx) + rotater := newFakeKeyRotater() + cfg := recordingencryptionv1.ServiceConfig{ + Authorizer: &fakeAuthorizer{}, + Logger: logtest.NewLogger(), + Uploader: fakeUploader{}, + KeyRotater: rotater, + } + + service, err := recordingencryptionv1.NewService(cfg) + require.NoError(t, err) + + _, err = service.RotateKey(authCtx, nil) + require.NoError(t, err) + require.Len(t, rotater.keys, 2) + + _, err = service.CompleteRotation(ctx, nil) + if c.expectErr { + require.True(t, trace.IsAccessDenied(err)) + require.Len(t, rotater.keys, 2) + } else { + require.NoError(t, err) + require.Len(t, rotater.keys, 1) + } + }) + } +} + +func TestRollbackRotation(t *testing.T) { + cases := []struct { + name string + ctx authz.Context + expectErr bool + }{ + { + name: "authorized Rollback", + ctx: newAuthCtx(authz.AdminActionAuthMFAVerified), + }, { + name: "unauthorized Rollback", + ctx: newAuthCtx(authz.AdminActionAuthUnauthorized), + expectErr: true, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + authCtx := withAuthCtx(t.Context(), newAuthCtx(authz.AdminActionAuthMFAVerified)) + ctx := withAuthCtx(t.Context(), c.ctx) + rotater := newFakeKeyRotater() + cfg := recordingencryptionv1.ServiceConfig{ + Authorizer: &fakeAuthorizer{}, + Logger: logtest.NewLogger(), + Uploader: fakeUploader{}, + KeyRotater: rotater, + } + + service, err := recordingencryptionv1.NewService(cfg) + require.NoError(t, err) + + _, err = service.RotateKey(authCtx, nil) + require.NoError(t, err) + require.Len(t, rotater.keys, 2) + + _, err = service.RollbackRotation(ctx, nil) + if c.expectErr { + require.True(t, trace.IsAccessDenied(err)) + require.Len(t, rotater.keys, 2) + } else { + require.NoError(t, err) + require.Len(t, rotater.keys, 1) + } + }) + } +} + +func TestGetRotationState(t *testing.T) { + cases := []struct { + name string + ctx authz.Context + expectErr bool + }{ + { + name: "authorized", + ctx: newAuthCtx(authz.AdminActionAuthMFAVerified), + }, { + name: "unauthorized", + ctx: newAuthCtx(authz.AdminActionAuthUnauthorized), + expectErr: true, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + ctx := withAuthCtx(t.Context(), c.ctx) + rotater := newFakeKeyRotater() + cfg := recordingencryptionv1.ServiceConfig{ + Authorizer: &fakeAuthorizer{}, + Logger: logtest.NewLogger(), + Uploader: fakeUploader{}, + KeyRotater: rotater, + } + + service, err := recordingencryptionv1.NewService(cfg) + require.NoError(t, err) + + res, err := service.GetRotationState(ctx, nil) + if c.expectErr { + require.Error(t, err) + require.Nil(t, res) + } else { + require.NoError(t, err) + require.Len(t, res.KeyPairStates, 1) + } + }) + } +} + +func newAuthCtx(action authz.AdminActionAuthState) authz.Context { + return authz.Context{ + AdminActionAuthState: action, + } +} + +type fakeUploader struct { + events.MultipartUploader +} + +type fakeAuthorizer struct{} + +func (f *fakeAuthorizer) Authorize(ctx context.Context) (*authz.Context, error) { + authCtx, ok := ctx.Value(authKey{}).(authz.Context) + if !ok { + return nil, errors.New("no auth") + } + + return &authCtx, nil +} + +type fakeKeyRotater struct { + keys []*recordingencryptionv1pb.FingerprintWithState +} + +func newFakeKeyRotater() *fakeKeyRotater { + return &fakeKeyRotater{ + keys: []*recordingencryptionv1pb.FingerprintWithState{ + { + Fingerprint: uuid.New().String(), + State: recordingencryptionv1pb.KeyPairState_KEY_PAIR_STATE_ACTIVE, + }, + }, + } +} + +func (f *fakeKeyRotater) RotateKey(ctx context.Context) error { + if len(f.keys) != 1 { + return errors.New("rotation in progress") + } + + if f.keys[0].State != recordingencryptionv1pb.KeyPairState_KEY_PAIR_STATE_ACTIVE { + return fmt.Errorf("keys in unexpected state: %v", f.keys[0].State) + } + + f.keys[0].State = recordingencryptionv1pb.KeyPairState_KEY_PAIR_STATE_ROTATING + f.keys = append(f.keys, &recordingencryptionv1pb.FingerprintWithState{ + Fingerprint: uuid.New().String(), + State: recordingencryptionv1pb.KeyPairState_KEY_PAIR_STATE_ACTIVE, + }) + + return nil +} + +func (f *fakeKeyRotater) CompleteRotation(ctx context.Context) error { + var keys []*recordingencryptionv1pb.FingerprintWithState + for _, key := range f.keys { + if key.State == recordingencryptionv1pb.KeyPairState_KEY_PAIR_STATE_ACTIVE { + keys = append(keys, key) + } + } + + f.keys = keys + return nil +} + +func (f *fakeKeyRotater) RollbackRotation(ctx context.Context) error { + var keys []*recordingencryptionv1pb.FingerprintWithState + for _, key := range f.keys { + if key.State == recordingencryptionv1pb.KeyPairState_KEY_PAIR_STATE_ROTATING { + keys = append(keys, key) + } + } + + f.keys = keys + return nil +} + +func (f *fakeKeyRotater) GetRotationState(ctx context.Context) ([]*recordingencryptionv1pb.FingerprintWithState, error) { + return f.keys, nil +} diff --git a/lib/cache/cache.go b/lib/cache/cache.go index 9ce70b00dbb8f..bdb22327f9bca 100644 --- a/lib/cache/cache.go +++ b/lib/cache/cache.go @@ -211,6 +211,7 @@ func ForAuth(cfg Config) Config { {Kind: types.KindWorkloadIdentity}, {Kind: types.KindHealthCheckConfig}, {Kind: types.KindBotInstance}, + {Kind: types.KindRecordingEncryption}, } cfg.QueueSize = defaults.AuthQueueSize // We don't want to enable partial health for auth cache because auth uses an event stream @@ -745,6 +746,8 @@ type Config struct { // BotInstanceService is the upstream service that we're caching BotInstanceService services.BotInstance Plugin services.Plugins + // RecordingEncryption manages state surrounding session recording encryption + RecordingEncryption services.RecordingEncryption } // CheckAndSetDefaults checks parameters and sets default values diff --git a/lib/cache/cache_test.go b/lib/cache/cache_test.go index 76502aa47e4b6..40fb31fa2fb86 100644 --- a/lib/cache/cache_test.go +++ b/lib/cache/cache_test.go @@ -55,6 +55,7 @@ import ( machineidv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/machineid/v1" notificationsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/notifications/v1" provisioningv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/provisioning/v1" + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" accessv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/scopes/access/v1" userprovisioningpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2" usertasksv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/usertasks/v1" @@ -170,6 +171,7 @@ type testPack struct { healthCheckConfig *local.HealthCheckConfigService botInstanceService *local.BotInstanceService plugin *local.PluginsService + recordingEncryption *local.RecordingEncryptionService } // testFuncs are functions to support testing an object in a cache. @@ -445,6 +447,11 @@ func newPackWithoutCache(dir string, opts ...packOption) (*testPack, error) { return nil, trace.Wrap(err) } + p.recordingEncryption, err = local.NewRecordingEncryptionService(p.backend) + if err != nil { + return nil, trace.Wrap(err) + } + return p, nil } @@ -502,6 +509,7 @@ func newPack(dir string, setupConfig func(c Config) Config, opts ...packOption) WorkloadIdentity: p.workloadIdentity, BotInstanceService: p.botInstanceService, Plugin: p.plugin, + RecordingEncryption: p.recordingEncryption, MaxRetryPeriod: 200 * time.Millisecond, EventsC: p.eventsC, })) @@ -762,6 +770,7 @@ func TestCompletenessInit(t *testing.T) { AutoUpdateService: p.autoUpdateService, ProvisioningStates: p.provisioningStates, WorkloadIdentity: p.workloadIdentity, + RecordingEncryption: p.recordingEncryption, MaxRetryPeriod: 200 * time.Millisecond, IdentityCenter: p.identityCenter, PluginStaticCredentials: p.pluginStaticCredentials, @@ -850,6 +859,7 @@ func TestCompletenessReset(t *testing.T) { IdentityCenter: p.identityCenter, PluginStaticCredentials: p.pluginStaticCredentials, WorkloadIdentity: p.workloadIdentity, + RecordingEncryption: p.recordingEncryption, MaxRetryPeriod: 200 * time.Millisecond, EventsC: p.eventsC, GitServers: p.gitServers, @@ -1008,6 +1018,7 @@ func TestListResources_NodesTTLVariant(t *testing.T) { IdentityCenter: p.identityCenter, PluginStaticCredentials: p.pluginStaticCredentials, WorkloadIdentity: p.workloadIdentity, + RecordingEncryption: p.recordingEncryption, MaxRetryPeriod: 200 * time.Millisecond, EventsC: p.eventsC, neverOK: true, // ensure reads are never healthy @@ -1107,6 +1118,7 @@ func initStrategy(t *testing.T) { IdentityCenter: p.identityCenter, PluginStaticCredentials: p.pluginStaticCredentials, WorkloadIdentity: p.workloadIdentity, + RecordingEncryption: p.recordingEncryption, MaxRetryPeriod: 200 * time.Millisecond, EventsC: p.eventsC, GitServers: p.gitServers, @@ -1913,6 +1925,7 @@ func TestCacheWatchKindExistsInEvents(t *testing.T) { types.KindPluginStaticCredentials: &types.PluginStaticCredentialsV1{}, types.KindGitServer: &types.ServerV2{}, types.KindWorkloadIdentity: types.Resource153ToLegacy(newWorkloadIdentity("some_identifier")), + types.KindRecordingEncryption: types.Resource153ToLegacy(newRecordingEncryption()), types.KindHealthCheckConfig: types.Resource153ToLegacy(newHealthCheckConfig(t, "some-name")), types.KindBotInstance: types.ProtoResource153ToLegacy(new(machineidv1.BotInstance)), scopedrole.KindScopedRole: types.Resource153ToLegacy(&accessv1.ScopedRole{}), @@ -1956,6 +1969,8 @@ func TestCacheWatchKindExistsInEvents(t *testing.T) { require.Empty(t, cmp.Diff(resource.(types.Resource153UnwrapperT[*autoupdate.AutoUpdateVersion]).UnwrapT(), uw.UnwrapT(), protocmp.Transform())) case types.Resource153UnwrapperT[*autoupdate.AutoUpdateConfig]: require.Empty(t, cmp.Diff(resource.(types.Resource153UnwrapperT[*autoupdate.AutoUpdateConfig]).UnwrapT(), uw.UnwrapT(), protocmp.Transform())) + case types.Resource153UnwrapperT[*recordingencryptionv1.RecordingEncryption]: + require.Empty(t, cmp.Diff(resource.(types.Resource153UnwrapperT[*recordingencryptionv1.RecordingEncryption]).UnwrapT(), uw.UnwrapT(), protocmp.Transform())) case types.Resource153UnwrapperT[*userprovisioningpb.StaticHostUser]: require.Empty(t, cmp.Diff(resource.(types.Resource153UnwrapperT[*userprovisioningpb.StaticHostUser]).UnwrapT(), uw.UnwrapT(), protocmp.Transform())) case types.Resource153UnwrapperT[*machineidv1.SPIFFEFederation]: diff --git a/lib/cache/collections.go b/lib/cache/collections.go index 585a564c576a8..b53244fbcd71e 100644 --- a/lib/cache/collections.go +++ b/lib/cache/collections.go @@ -33,6 +33,7 @@ import ( machineidv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/machineid/v1" notificationsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/notifications/v1" provisioningv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/provisioning/v1" + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" userprovisioningv2 "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2" usertasksv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/usertasks/v1" workloadidentityv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1" @@ -139,6 +140,7 @@ type collections struct { secReportsStates *collection[*secreports.ReportState, securityReportStateIndex] botInstances *collection[*machineidv1.BotInstance, botInstanceIndex] plugins *collection[types.Plugin, pluginIndex] + recordingEncryption *collection[*recordingencryptionv1.RecordingEncryption, recordingEncryptionIndex] } // isKnownUncollectedKind is true if a resource kind is not stored in @@ -739,10 +741,19 @@ func setupCollections(c Config) (*collections, error) { } out.plugins = collect out.byKind[resourceKind] = out.plugins + case types.KindRecordingEncryption: + collect, err := newRecordingEncryptionCollection(c.RecordingEncryption, watch) + if err != nil { + return nil, trace.Wrap(err) + } + + out.recordingEncryption = collect + out.byKind[resourceKind] = out.recordingEncryption default: if _, ok := out.byKind[resourceKind]; !ok { return nil, trace.BadParameter("resource %q is not supported", watch.Kind) } + } } diff --git a/lib/cache/recording_encryption.go b/lib/cache/recording_encryption.go new file mode 100644 index 0000000000000..4bff49fd1c673 --- /dev/null +++ b/lib/cache/recording_encryption.go @@ -0,0 +1,84 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package cache + +import ( + "context" + + "github.com/gravitational/trace" + "google.golang.org/protobuf/proto" + + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/services" +) + +type recordingEncryptionIndex string + +const recordingEncryptionNameIndex recordingEncryptionIndex = "name" + +func newRecordingEncryptionCollection(upstream services.RecordingEncryption, w types.WatchKind) (*collection[*recordingencryptionv1.RecordingEncryption, recordingEncryptionIndex], error) { + if upstream == nil { + return nil, trace.BadParameter("missing parameter RecordingEncryption") + } + + return &collection[*recordingencryptionv1.RecordingEncryption, recordingEncryptionIndex]{ + store: newStore(types.KindRecordingEncryption, proto.CloneOf[*recordingencryptionv1.RecordingEncryption], map[recordingEncryptionIndex]func(*recordingencryptionv1.RecordingEncryption) string{ + recordingEncryptionNameIndex: func(r *recordingencryptionv1.RecordingEncryption) string { + return r.GetMetadata().GetName() + }, + }), + fetcher: func(ctx context.Context, loadSecrets bool) ([]*recordingencryptionv1.RecordingEncryption, error) { + recordingEncryption, err := upstream.GetRecordingEncryption(ctx) + if err != nil { + return nil, trace.Wrap(err) + } + + return []*recordingencryptionv1.RecordingEncryption{recordingEncryption}, nil + }, + headerTransform: func(hdr *types.ResourceHeader) *recordingencryptionv1.RecordingEncryption { + return &recordingencryptionv1.RecordingEncryption{ + Kind: hdr.Kind, + Version: hdr.Version, + Metadata: &headerv1.Metadata{ + Name: hdr.Metadata.Name, + }, + } + }, + watch: w, + }, nil +} + +// GetRecordingEncryption returns the cached RecordingEncryption for the cluster +func (c *Cache) GetRecordingEncryption(ctx context.Context) (*recordingencryptionv1.RecordingEncryption, error) { + ctx, span := c.Tracer.Start(ctx, "cache/GetRecordingEncryption") + defer span.End() + + getter := genericGetter[*recordingencryptionv1.RecordingEncryption, recordingEncryptionIndex]{ + cache: c, + collection: c.collections.recordingEncryption, + index: recordingEncryptionNameIndex, + upstreamGet: func(ctx context.Context, ident string) (*recordingencryptionv1.RecordingEncryption, error) { + encryption, err := c.Config.RecordingEncryption.GetRecordingEncryption(ctx) + return encryption, trace.Wrap(err) + }, + } + + out, err := getter.get(ctx, types.MetaNameRecordingEncryption) + return out, trace.Wrap(err) +} diff --git a/lib/cache/recording_encryption_test.go b/lib/cache/recording_encryption_test.go new file mode 100644 index 0000000000000..1b16e310740da --- /dev/null +++ b/lib/cache/recording_encryption_test.go @@ -0,0 +1,81 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package cache + +import ( + "context" + "testing" + + "github.com/gravitational/trace" + + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/api/types" +) + +func newRecordingEncryption() *recordingencryptionv1.RecordingEncryption { + return &recordingencryptionv1.RecordingEncryption{ + Kind: types.KindRecordingEncryption, + Version: types.V1, + Metadata: &headerv1.Metadata{ + Name: types.MetaNameRecordingEncryption, + }, + Spec: &recordingencryptionv1.RecordingEncryptionSpec{ + ActiveKeyPairs: nil, + }, + } +} + +// TestRecordingEncryption tests that CRUD operations on the RecordingEncryption resource are +// replicated from the backend to the cache. +func TestRecordingEncryption(t *testing.T) { + t.Parallel() + + p := newTestPack(t, ForAuth) + t.Cleanup(p.Close) + + testResources153(t, p, testFuncs153[*recordingencryptionv1.RecordingEncryption]{ + newResource: func(name string) (*recordingencryptionv1.RecordingEncryption, error) { + return newRecordingEncryption(), nil + }, + create: func(ctx context.Context, item *recordingencryptionv1.RecordingEncryption) error { + _, err := p.recordingEncryption.CreateRecordingEncryption(ctx, item) + return trace.Wrap(err) + }, + update: func(ctx context.Context, item *recordingencryptionv1.RecordingEncryption) error { + _, err := p.recordingEncryption.UpdateRecordingEncryption(ctx, item) + return trace.Wrap(err) + }, + list: func(ctx context.Context) ([]*recordingencryptionv1.RecordingEncryption, error) { + item, err := p.recordingEncryption.GetRecordingEncryption(ctx) + if trace.IsNotFound(err) { + return []*recordingencryptionv1.RecordingEncryption{}, nil + } + return []*recordingencryptionv1.RecordingEncryption{item}, trace.Wrap(err) + }, + cacheList: func(ctx context.Context) ([]*recordingencryptionv1.RecordingEncryption, error) { + item, err := p.cache.GetRecordingEncryption(ctx) + if trace.IsNotFound(err) { + return []*recordingencryptionv1.RecordingEncryption{}, nil + } + return []*recordingencryptionv1.RecordingEncryption{item}, trace.Wrap(err) + }, + deleteAll: func(ctx context.Context) error { + return trace.Wrap(p.recordingEncryption.DeleteRecordingEncryption(ctx)) + }, + }) +} diff --git a/lib/client/player.go b/lib/client/player.go index 4a87d352a35e6..652ec3649ac73 100644 --- a/lib/client/player.go +++ b/lib/client/player.go @@ -51,7 +51,8 @@ func (p *playFromFileStreamer) StreamSessionEvents( } defer f.Close() - pr := events.NewProtoReader(f) + pr := events.NewProtoReader(f, nil) + for i := int64(0); ; i++ { evt, err := pr.Read(ctx) if err != nil { diff --git a/lib/config/configuration.go b/lib/config/configuration.go index c7b8b7a3773b7..fad50a0359993 100644 --- a/lib/config/configuration.go +++ b/lib/config/configuration.go @@ -959,10 +959,24 @@ func applyAuthConfig(fc *FileConfig, cfg *servicecfg.Config) error { // Only override session recording configuration if either field is // specified in file configuration. if fc.Auth.hasCustomSessionRecording() { - cfg.Auth.SessionRecordingConfig, err = types.NewSessionRecordingConfigFromConfigFile(types.SessionRecordingConfigSpecV2{ + src := types.SessionRecordingConfigSpecV2{ Mode: fc.Auth.SessionRecording, ProxyChecksHostKeys: fc.Auth.ProxyChecksHostKeys, - }) + } + + if fc.Auth.SessionRecordingConfig != nil { + if src.Mode != "" { + return trace.BadParameter("cannot set both session_recording and session_recording_config at the same time, prefer session_recording_config.mode") + } + + if src.ProxyChecksHostKeys != nil { + return trace.BadParameter("cannot set both proxy_checks_host_keys and session_recording_config at the same time, prefer session_recording_config.proxy_checks_host_keys") + } + + src = fc.Auth.SessionRecordingConfig.toSpec() + } + + cfg.Auth.SessionRecordingConfig, err = types.NewSessionRecordingConfigFromConfigFile(src) if err != nil { return trace.Wrap(err) } @@ -2596,6 +2610,10 @@ func Configure(clf *CommandLineFlags, cfg *servicecfg.Config, legacyAppFlags boo !cfg.Auth.SessionRecordingConfig.GetProxyChecksHostKeys() { return trace.BadParameter("non-FIPS compliant proxy settings: \"proxy_checks_host_keys\" must be true") } + + if err := services.ValidateSessionRecordingConfig(cfg.Auth.SessionRecordingConfig, clf.FIPS, modules.GetModules().Features().Cloud); err != nil { + return trace.Wrap(err) + } } } diff --git a/lib/config/fileconf.go b/lib/config/fileconf.go index d13309e5e6340..655b0c4b7c530 100644 --- a/lib/config/fileconf.go +++ b/lib/config/fileconf.go @@ -744,6 +744,10 @@ type Auth struct { // determines if the proxy will check the host key of the client or not. ProxyChecksHostKeys *types.BoolOption `yaml:"proxy_checks_host_keys,omitempty"` + // SessionRecordingConfig configures how session recording should be handled including things like + // encryption and key management. + SessionRecordingConfig *SessionRecordingConfig `yaml:"session_recording_config,omitempty"` + // LicenseFile is a path to the license file. The path can be either absolute or // relative to the global data dir LicenseFile string `yaml:"license_file,omitempty"` @@ -885,7 +889,8 @@ func (a *Auth) hasCustomNetworkingConfig() bool { func (a *Auth) hasCustomSessionRecording() bool { empty := Auth{} return a.SessionRecording != empty.SessionRecording || - a.ProxyChecksHostKeys != empty.ProxyChecksHostKeys + a.ProxyChecksHostKeys != empty.ProxyChecksHostKeys || + a.SessionRecordingConfig != empty.SessionRecordingConfig } // CAKeyParams configures how CA private keys will be created and stored. @@ -2913,3 +2918,50 @@ func readJamfPasswordFile(path, key string) (string, error) { return pwd, nil } + +// SessionRecordingEncryptionConfig is the session_recording_config.encryption +// section of the Teleport config file. It maps directly to [types.SessionRecordingEncryptionConfig] +type SessionRecordingEncryptionConfig struct { + Enabled bool `yaml:"enabled,omitempty"` + ManualKeyManagement *struct { + Enabled bool `yaml:"enabled,omitempty"` + ActiveKeys []*types.KeyLabel `yaml:"active_keys,omitempty"` + RotatedKeys []*types.KeyLabel `yaml:"rotated_keys,omitempty"` + } `yaml:"manual_key_management,omitempty"` +} + +// SessionRecordingConfig is the session_recording_config section of the Teleport config file. +// It maps directly to [types.SessionRecordingConfigSpecV2] +type SessionRecordingConfig struct { + Mode string `yaml:"mode"` + ProxyChecksHostKeys *types.BoolOption `yaml:"proxy_checks_host_keys,omitempty"` + Encryption *SessionRecordingEncryptionConfig `yaml:"encryption,omitempty"` +} + +// toSpec converts SessionRecordingConfig into a types.SessionRecordingConfigSpecV2 so it can +// be used to initialize session recording. +func (src *SessionRecordingConfig) toSpec() types.SessionRecordingConfigSpecV2 { + if src == nil { + return types.SessionRecordingConfigSpecV2{} + } + + var encryption *types.SessionRecordingEncryptionConfig + if src.Encryption != nil { + encryption = &types.SessionRecordingEncryptionConfig{ + Enabled: src.Encryption.Enabled, + } + if src.Encryption.ManualKeyManagement != nil { + encryption.ManualKeyManagement = &types.ManualKeyManagementConfig{ + Enabled: src.Encryption.ManualKeyManagement.Enabled, + ActiveKeys: src.Encryption.ManualKeyManagement.ActiveKeys, + RotatedKeys: src.Encryption.ManualKeyManagement.RotatedKeys, + } + } + } + + return types.SessionRecordingConfigSpecV2{ + Mode: src.Mode, + ProxyChecksHostKeys: src.ProxyChecksHostKeys, + Encryption: encryption, + } +} diff --git a/lib/cryptosuites/cryptosuitestest/precompute.go b/lib/cryptosuites/cryptosuitestest/precompute.go index 9fffeb12684ce..564c859605004 100644 --- a/lib/cryptosuites/cryptosuitestest/precompute.go +++ b/lib/cryptosuites/cryptosuitestest/precompute.go @@ -30,17 +30,24 @@ import ( // save on CPU usage. func PrecomputeRSAKeys(ctx context.Context) { internalrsa.StartPrecomputeOnce.Do(func() { - go precomputeTestKeys(ctx) + go precomputeTestKeys(ctx, constants.RSAKeySize) + go precomputeTestKeys(ctx, 4096) }) } -func precomputeTestKeys(ctx context.Context) { - generatedTestKeys := generateTestKeys(ctx) - keysToReuse := make([]*rsa.PrivateKey, 0, testKeysNumber) - for range testKeysNumber { +func precomputeTestKeys(ctx context.Context, bitSize int) { + source := internalrsa.PrecomputedKeys + count := testKeysNumber + if bitSize == 4096 { + source = internalrsa.PrecomputedKeys4096 + count = testKeysNumber4096 + } + generatedTestKeys := generateTestKeys(ctx, bitSize) + keysToReuse := make([]*rsa.PrivateKey, 0, count) + for range count { select { case k := <-generatedTestKeys: - internalrsa.PrecomputedKeys <- k + source <- k keysToReuse = append(keysToReuse, k) case <-ctx.Done(): return @@ -50,7 +57,7 @@ func precomputeTestKeys(ctx context.Context) { for { for _, k := range keysToReuse { select { - case internalrsa.PrecomputedKeys <- k: + case source <- k: case <-ctx.Done(): return } @@ -61,13 +68,20 @@ func precomputeTestKeys(ctx context.Context) { // testKeysNumber is the number of RSA keys generated in tests. const testKeysNumber = 25 -func generateTestKeys(ctx context.Context) <-chan *rsa.PrivateKey { - generatedTestKeys := make(chan *rsa.PrivateKey, testKeysNumber) - for range testKeysNumber { +// testKeysNumber is the number of RSA 4096 keys generated in tests. +const testKeysNumber4096 = 10 + +func generateTestKeys(ctx context.Context, bitSize int) <-chan *rsa.PrivateKey { + count := testKeysNumber + if bitSize == 4096 { + count = testKeysNumber4096 + } + generatedTestKeys := make(chan *rsa.PrivateKey, count) + for range count { // Generate each key in a separate goroutine to take advantage of // multiple cores if possible. go func() { - private, err := generateRSAPrivateKey() + private, err := generateRSAPrivateKey(bitSize) if err != nil { // Use only in tests. Safe to panic. panic(err) @@ -84,7 +98,7 @@ func generateTestKeys(ctx context.Context) <-chan *rsa.PrivateKey { return generatedTestKeys } -func generateRSAPrivateKey() (*rsa.PrivateKey, error) { +func generateRSAPrivateKey(bitSize int) (*rsa.PrivateKey, error) { //nolint:forbidigo // This is the one function allowed to generate RSA keys. - return rsa.GenerateKey(rand.Reader, constants.RSAKeySize) + return rsa.GenerateKey(rand.Reader, bitSize) } diff --git a/lib/cryptosuites/internal/rsa/rsa.go b/lib/cryptosuites/internal/rsa/rsa.go index 7653b187eab33..38b6f6bf73068 100644 --- a/lib/cryptosuites/internal/rsa/rsa.go +++ b/lib/cryptosuites/internal/rsa/rsa.go @@ -35,21 +35,35 @@ var ( // PrecomputedKeys is a queue of cached keys ready for usage. PrecomputedKeys = make(chan *rsa.PrivateKey, 25) + // PrecomputedKeys4096 is a queue of cached 4096-bit keys ready for usage. + PrecomputedKeys4096 = make(chan *rsa.PrivateKey, 10) + // StartPrecomputeOnce is used to start the background task that precomputes key pairs. StartPrecomputeOnce sync.Once ) // GenerateKey returns a newly generated RSA private key. func GenerateKey() (*rsa.PrivateKey, error) { - return getOrGenerateRSAPrivateKey() + return getOrGenerateRSAPrivateKey(constants.RSAKeySize) +} + +// GenerateKey4096 generates a 4096-bit RSA private key meant for use in asymmetric encryption use cases such as +// encrypted session recordings. +func GenerateKey4096() (*rsa.PrivateKey, error) { + return getOrGenerateRSAPrivateKey(4096) } -func getOrGenerateRSAPrivateKey() (*rsa.PrivateKey, error) { +func getOrGenerateRSAPrivateKey(bitSize int) (*rsa.PrivateKey, error) { + source := PrecomputedKeys + if bitSize == 4096 { + source = PrecomputedKeys4096 + } + select { - case k := <-PrecomputedKeys: + case k := <-source: return k, nil default: - rsaKeyPair, err := generateRSAPrivateKey() + rsaKeyPair, err := generateRSAPrivateKey(bitSize) if err != nil { return nil, err } @@ -57,15 +71,15 @@ func getOrGenerateRSAPrivateKey() (*rsa.PrivateKey, error) { } } -func generateRSAPrivateKey() (*rsa.PrivateKey, error) { +func generateRSAPrivateKey(bits int) (*rsa.PrivateKey, error) { //nolint:forbidigo // This is the one function allowed to generate RSA keys. - return rsa.GenerateKey(rand.Reader, constants.RSAKeySize) + return rsa.GenerateKey(rand.Reader, bits) } func precomputeKeys() { const backoff = time.Second * 30 for { - rsaPrivateKey, err := generateRSAPrivateKey() + rsaPrivateKey, err := generateRSAPrivateKey(constants.RSAKeySize) if err != nil { log.ErrorContext(context.Background(), "Failed to precompute key pair, retrying (this might be a bug).", slog.Any("error", err), slog.Duration("backoff", backoff)) diff --git a/lib/cryptosuites/suites.go b/lib/cryptosuites/suites.go index bbcf13ef61802..ae8b6bf638560 100644 --- a/lib/cryptosuites/suites.go +++ b/lib/cryptosuites/suites.go @@ -128,6 +128,9 @@ const ( // BoundKeypairCAJWT represents the JWT key for the bound_keypair CA. BoundKeypairCAJWT + // RecordingKeyWrapping is a key used for wrapping session recording decryption keys. + RecordingKeyWrapping + // keyPurposeMax is 1 greater than the last valid key purpose, used to test that all values less than this // are valid for each suite. keyPurposeMax @@ -141,6 +144,8 @@ const ( // RSA2048 represents RSA 2048-bit keys. RSA2048 + // RSA4096 represents RSA 4096-bit keys. + RSA4096 // ECDSAP256 represents ECDSA keys using NIST curve P-256. ECDSAP256 // Ed25519 represents Ed25519 keys. @@ -156,6 +161,8 @@ func (a Algorithm) String() string { return "algorithm unspecified" case RSA2048: return "RSA2048" + case RSA4096: + return "RSA4096" case ECDSAP256: return "ECDSAP256" case Ed25519: @@ -204,11 +211,12 @@ var ( ProxyToDatabaseAgent: RSA2048, ProxyKubeClient: RSA2048, // EC2InstanceConnect has always used Ed25519 by default. - EC2InstanceConnect: Ed25519, - GitClient: Ed25519, - AWSRACATLS: ECDSAP256, - BoundKeypairJoining: Ed25519, - BoundKeypairCAJWT: ECDSAP256, + EC2InstanceConnect: Ed25519, + GitClient: Ed25519, + AWSRACATLS: ECDSAP256, + BoundKeypairJoining: Ed25519, + BoundKeypairCAJWT: ECDSAP256, + RecordingKeyWrapping: RSA4096, } // balancedV1 strikes a balance between security, compatibility, and @@ -243,6 +251,7 @@ var ( AWSRACATLS: ECDSAP256, BoundKeypairJoining: Ed25519, BoundKeypairCAJWT: Ed25519, + RecordingKeyWrapping: RSA4096, } // fipsv1 is an algorithm suite tailored for FIPS compliance. It is based on @@ -278,6 +287,7 @@ var ( AWSRACATLS: ECDSAP256, BoundKeypairJoining: ECDSAP256, BoundKeypairCAJWT: ECDSAP256, + RecordingKeyWrapping: RSA4096, } // hsmv1 in an algorithm suite tailored for clusters using an HSM or KMS @@ -315,6 +325,7 @@ var ( AWSRACATLS: ECDSAP256, BoundKeypairJoining: Ed25519, BoundKeypairCAJWT: ECDSAP256, + RecordingKeyWrapping: RSA4096, } allSuites = map[types.SignatureAlgorithmSuite]suite{ @@ -463,6 +474,8 @@ func GenerateKeyWithAlgorithm(alg Algorithm) (crypto.Signer, error) { switch alg { case RSA2048: return generateRSA2048() + case RSA4096: + return generateRSA4096() case ECDSAP256: return generateECDSAP256() case Ed25519: @@ -472,6 +485,16 @@ func GenerateKeyWithAlgorithm(alg Algorithm) (crypto.Signer, error) { } } +// GenerateDecrypterWithAlgorithm generates a new cryptographic keypair with the given algorithm meant for decryption. +func GenerateDecrypterWithAlgorithm(alg Algorithm) (crypto.Decrypter, error) { + switch alg { + case RSA4096: + return generateRSA4096() + default: + return nil, trace.BadParameter("unsupported decryption key algorithm %v", alg) + } +} + // GeneratePrivateKeyWithAlgorithm is exactly like [GenerateKeyWithAlgorithm] // but wraps the returned key in a [*keys.PrivateKey] for convenience. func GeneratePrivateKeyWithAlgorithm(alg Algorithm) (*keys.PrivateKey, error) { @@ -488,6 +511,11 @@ func generateRSA2048() (*rsa.PrivateKey, error) { return key, trace.Wrap(err) } +func generateRSA4096() (*rsa.PrivateKey, error) { + key, err := internalrsa.GenerateKey4096() + return key, trace.Wrap(err) +} + func generateECDSAP256() (*ecdsa.PrivateKey, error) { key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) return key, trace.Wrap(err) diff --git a/lib/events/api.go b/lib/events/api.go index 0146a2ae55113..61de7ffa9f2ac 100644 --- a/lib/events/api.go +++ b/lib/events/api.go @@ -22,6 +22,7 @@ import ( "context" "fmt" "io" + "iter" "math" "time" @@ -1118,6 +1119,7 @@ type StreamEmitter interface { type AuditLogSessionStreamer interface { AuditLogger SessionStreamer + EncryptedRecordingUploader } // SessionStreamer supports streaming session chunks or events. @@ -1132,6 +1134,12 @@ type SessionStreamer interface { StreamSessionEvents(ctx context.Context, sessionID session.ID, startIndex int64) (chan apievents.AuditEvent, chan error) } +// EncryptedRecordingUploader takes a session ID and a sequence of encrypted +// recording parts and uploads an encrypted session recording. +type EncryptedRecordingUploader interface { + UploadEncryptedRecording(ctx context.Context, sessionID string, parts iter.Seq2[[]byte, error]) error +} + type SearchEventsRequest struct { // From is oldest date of returned events, can be zero. From time.Time diff --git a/lib/events/auditlog.go b/lib/events/auditlog.go index 6148e27393ccd..308fe31516b67 100644 --- a/lib/events/auditlog.go +++ b/lib/events/auditlog.go @@ -19,10 +19,12 @@ package events import ( + "bytes" "context" "errors" "io" "io/fs" + "iter" "log/slog" "os" "path/filepath" @@ -203,6 +205,9 @@ type AuditLog struct { // localLog is a local events log used // to emit audit events if no external log has been specified localLog *FileLog + + // decrypter wraps session replay with decryption + decrypter DecryptionWrapper } // AuditLogConfig specifies configuration for AuditLog server @@ -247,6 +252,9 @@ type AuditLogConfig struct { // Context is audit log context Context context.Context + + // Decrypter wraps session replay with decryption + Decrypter DecryptionWrapper } // CheckAndSetDefaults checks and sets defaults @@ -304,6 +312,7 @@ func NewAuditLog(cfg AuditLogConfig) (*AuditLog, error) { activeDownloads: make(map[string]context.Context), ctx: ctx, cancel: cancel, + decrypter: cfg.Decrypter, } // create a directory for audit logs, audit log does not create // session logs before migrations are run in case if the directory @@ -572,7 +581,7 @@ func (l *AuditLog) StreamSessionEvents(ctx context.Context, sessionID session.ID return } - protoReader := NewProtoReader(rawSession) + protoReader := NewProtoReader(rawSession, l.decrypter) defer protoReader.Close() firstEvent := true @@ -611,6 +620,39 @@ func (l *AuditLog) StreamSessionEvents(ctx context.Context, sessionID session.ID return c, e } +// UploadEncryptedRecording uploads encrypted recordings using the AuditLog's configured UploadHandler. +func (l *AuditLog) UploadEncryptedRecording(ctx context.Context, sessionID string, parts iter.Seq2[[]byte, error]) error { + sessID, err := session.ParseID(sessionID) + if err != nil { + return trace.Wrap(err) + } + upload, err := l.UploadHandler.CreateUpload(ctx, *sessID) + if err != nil { + return trace.Wrap(err, "creating upload") + } + + var streamParts []StreamPart + var partNumber int64 + for part, err := range parts { + if err != nil { + return trace.Wrap(err) + } + + if err := l.UploadHandler.ReserveUploadPart(ctx, *upload, partNumber); err != nil { + return trace.Wrap(err, "reserving upload part") + } + + streamPart, err := l.UploadHandler.UploadPart(ctx, *upload, partNumber, bytes.NewReader(part)) + if err != nil { + return trace.Wrap(err, "uploading part") + } + streamParts = append(streamParts, *streamPart) + partNumber++ + } + + return trace.Wrap(l.UploadHandler.CompleteUpload(ctx, *upload, streamParts), "completing upload") +} + // getLocalLog returns the local (file based) AuditLogger. func (l *AuditLog) getLocalLog() AuditLogger { l.RLock() diff --git a/lib/events/discard.go b/lib/events/discard.go index ad091008bb4a7..da16ffbfff106 100644 --- a/lib/events/discard.go +++ b/lib/events/discard.go @@ -20,6 +20,7 @@ package events import ( "context" + "iter" "log/slog" "sync/atomic" @@ -71,6 +72,14 @@ func (d *DiscardAuditLog) StreamSessionEvents(ctx context.Context, sessionID ses return c, e } +func (d *DiscardAuditLog) UploadEncryptedRecording(ctx context.Context, sessionID string, parts iter.Seq2[[]byte, error]) error { + return nil +} + +func (d *DiscardAuditLog) GetMultipartUploader() MultipartUploader { + return nil +} + // NewDiscardRecorder returns a [SessionRecorderChecker] that discards events. func NewDiscardRecorder() *DiscardRecorder { return &DiscardRecorder{ diff --git a/lib/events/emitter_test.go b/lib/events/emitter_test.go index c7b4cc2076d77..99fbb69fb4183 100644 --- a/lib/events/emitter_test.go +++ b/lib/events/emitter_test.go @@ -108,7 +108,7 @@ func TestProtoStreamer(t *testing.T) { require.NoError(t, err) for _, part := range parts { - reader := events.NewProtoReader(bytes.NewReader(part)) + reader := events.NewProtoReader(bytes.NewReader(part), nil) out, err := reader.ReadAll(ctx) require.NoError(t, err, "part crash %#v", part) outEvents = append(outEvents, out...) @@ -256,7 +256,7 @@ func TestExport(t *testing.T) { _, err := f.Write(part) require.NoError(t, err) } - reader := events.NewProtoReader(io.MultiReader(readers...)) + reader := events.NewProtoReader(io.MultiReader(readers...), nil) outEvents, err := reader.ReadAll(ctx) require.NoError(t, err) diff --git a/lib/events/filesessions/fileasync.go b/lib/events/filesessions/fileasync.go index cf2cdf9e87af7..e67d03a59fe14 100644 --- a/lib/events/filesessions/fileasync.go +++ b/lib/events/filesessions/fileasync.go @@ -19,6 +19,7 @@ package filesessions import ( + "bytes" "context" "errors" "fmt" @@ -63,6 +64,8 @@ type UploaderConfig struct { EventsC chan events.UploadEvent // Component is used for logging purposes Component string + // EncryptedRecordingUploader uploads encrypted session recordings + EncryptedRecordingUploader events.EncryptedRecordingUploader } // CheckAndSetDefaults checks and sets default values of UploaderConfig @@ -375,6 +378,64 @@ func (u *upload) removeFiles() error { return trace.NewAggregate(errs...) } +var errSkipEncryptedUpload = errors.New("skip encrypted upload") + +func (u *Uploader) uploadEncryptedRecording(ctx context.Context, sessionID string, in io.Reader) error { + if u.cfg.EncryptedRecordingUploader == nil { + return trace.Wrap(errSkipEncryptedUpload, "no encrypted uploader configured") + } + + partIter := func(yield func([]byte, error) bool) { + var buf bytes.Buffer + for { + buf.Reset() + header, err := events.ParsePartHeader(in) + if err != nil { + if errors.Is(err, io.EOF) { + break + } + + yield(nil, trace.Wrap(err)) + return + } + + if header.Flags&events.ProtoStreamFlagEncrypted == 0 { + yield(nil, trace.Wrap(errSkipEncryptedUpload, "recording not encrypted")) + return + } + + if _, err := buf.Write(header.Bytes()); err != nil { + yield(nil, trace.Wrap(err)) + return + } + + totalPartSize := int64(header.PartSize + header.PaddingSize) + reader := io.LimitReader(in, totalPartSize) + copied, err := io.Copy(&buf, reader) + if err != nil && !errors.Is(err, io.EOF) { + yield(nil, trace.Wrap(err)) + return + } + + if copied != totalPartSize { + yield(nil, trace.Errorf("copied %d bytes of recording part instead of expected %d", copied, totalPartSize)) + return + } + + if !yield(buf.Bytes(), nil) { + return + } + } + } + + u.log.DebugContext(ctx, "uploading encrypted recording", "session_id", sessionID) + if err := u.cfg.EncryptedRecordingUploader.UploadEncryptedRecording(ctx, sessionID, partIter); err != nil { + return trace.Wrap(err) + } + + return nil +} + func (u *Uploader) startUpload(ctx context.Context, fileName string) (err error) { sessionID, err := sessionIDFromPath(fileName) if err != nil { @@ -439,9 +500,29 @@ func (u *Uploader) startUpload(ctx context.Context, fileName string) (err error) return trace.Wrap(err, "uploader could not acquire file lock for %q", sessionFilePath) } + if err := u.uploadEncryptedRecording(ctx, sessionID.String(), sessionFile); !errors.Is(err, errSkipEncryptedUpload) { + if err != nil { + return trace.Wrap(err) + } + + if err := os.Remove(sessionFile.Name()); err != nil { + return trace.Wrap(err) + } + + return nil + } + + u.log.DebugContext(ctx, "upload not encrypted, proceeding with plaintext uploader") + // ensure sessionFile starts at 0 after attempted encrypted upload + if _, err := sessionFile.Seek(0, io.SeekStart); err != nil { + return trace.Wrap(err) + } + + protoReader := events.NewProtoReader(sessionFile, nil) + upload := &upload{ sessionID: sessionID, - reader: events.NewProtoReader(sessionFile), + reader: protoReader, file: sessionFile, fileUnlockFn: unlock, } diff --git a/lib/events/filesessions/fileasync_chaos_test.go b/lib/events/filesessions/fileasync_chaos_test.go index 26e7a2b522911..17afa3609ce94 100644 --- a/lib/events/filesessions/fileasync_chaos_test.go +++ b/lib/events/filesessions/fileasync_chaos_test.go @@ -122,7 +122,7 @@ func TestChaosUpload(t *testing.T) { go uploader.Serve(ctx) defer uploader.Close() - fileStreamer, err := NewStreamer(scanDir) + fileStreamer, err := NewStreamer(scanDir, nil) require.NoError(t, err) parallelStreams := 20 diff --git a/lib/events/filesessions/fileasync_test.go b/lib/events/filesessions/fileasync_test.go index a015bde8ec15c..f26e585fc33c8 100644 --- a/lib/events/filesessions/fileasync_test.go +++ b/lib/events/filesessions/fileasync_test.go @@ -47,7 +47,7 @@ func TestUploadOK(t *testing.T) { // wait until uploader blocks on the clock p.clock.BlockUntil(1) - fileStreamer, err := NewStreamer(p.scanDir) + fileStreamer, err := NewStreamer(p.scanDir, nil) require.NoError(t, err) inEvents := eventstest.GenerateTestSession(eventstest.SessionParams{PrintEvents: 1024}) @@ -84,8 +84,8 @@ func TestUploadParallel(t *testing.T) { sessions := make(map[string][]apievents.AuditEvent) - for i := 0; i < 5; i++ { - fileStreamer, err := NewStreamer(p.scanDir) + for range 5 { + fileStreamer, err := NewStreamer(p.scanDir, nil) require.NoError(t, err) sessionEvents := eventstest.GenerateTestSession(eventstest.SessionParams{PrintEvents: 1024}) @@ -382,7 +382,7 @@ func TestUploadBackoff(t *testing.T) { // wait until uploader blocks on the clock before creating the stream p.clock.BlockUntil(1) - fileStreamer, err := NewStreamer(p.scanDir) + fileStreamer, err := NewStreamer(p.scanDir, nil) require.NoError(t, err) inEvents := eventstest.GenerateTestSession(eventstest.SessionParams{PrintEvents: 4096}) @@ -589,7 +589,7 @@ func runResume(t *testing.T, testCase resumeTestCase) { defer uploader.Close() - fileStreamer, err := NewStreamer(scanDir) + fileStreamer, err := NewStreamer(scanDir, nil) require.NoError(t, err) inEvents := eventstest.GenerateTestSession(eventstest.SessionParams{PrintEvents: 1024}) @@ -669,7 +669,7 @@ func readStream(ctx context.Context, t *testing.T, uploadID string, uploader *ev var reader *events.ProtoReader for i, part := range parts { if i == 0 { - reader = events.NewProtoReader(bytes.NewReader(part)) + reader = events.NewProtoReader(bytes.NewReader(part), nil) } else { err := reader.Reset(bytes.NewReader(part)) require.NoError(t, err) diff --git a/lib/events/filesessions/filestream.go b/lib/events/filesessions/filestream.go index 2e7830b9d33e3..49ce1b64113fc 100644 --- a/lib/events/filesessions/filestream.go +++ b/lib/events/filesessions/filestream.go @@ -78,7 +78,7 @@ const ( ) // NewStreamer creates a streamer sending uploads to disk -func NewStreamer(dir string) (*events.ProtoStreamer, error) { +func NewStreamer(dir string, encrypter events.EncryptionWrapper) (*events.ProtoStreamer, error) { handler, err := NewHandler(Config{Directory: dir, OpenFile: GetOpenFileFunc()}) if err != nil { return nil, trace.Wrap(err) @@ -86,6 +86,7 @@ func NewStreamer(dir string) (*events.ProtoStreamer, error) { return events.NewProtoStreamer(events.ProtoStreamerConfig{ Uploader: handler, MinUploadBytes: minUploadBytes, + Encrypter: encrypter, }) } diff --git a/lib/events/playback.go b/lib/events/playback.go index ef7bea65d93f4..ed785cc4732db 100644 --- a/lib/events/playback.go +++ b/lib/events/playback.go @@ -53,7 +53,7 @@ func DetectFormat(r io.ReadSeeker) (*Header, error) { return nil, trace.ConvertSystemError(err) } protocolVersion := binary.BigEndian.Uint64(version) - if protocolVersion == ProtoStreamV1 { + if protocolVersion >= ProtoStreamV1 && protocolVersion <= ProtoStreamV2 { return &Header{ Proto: true, ProtoVersion: int64(protocolVersion), @@ -83,7 +83,7 @@ func Export(ctx context.Context, rs io.ReadSeeker, w io.Writer, exportFormat str } switch { case format.Proto: - protoReader := NewProtoReader(rs) + protoReader := NewProtoReader(rs, nil) for { event, err := protoReader.Read(ctx) if err != nil { diff --git a/lib/events/recorder/recorder.go b/lib/events/recorder/recorder.go index 3559df2175b20..916704dae5a38 100644 --- a/lib/events/recorder/recorder.go +++ b/lib/events/recorder/recorder.go @@ -29,6 +29,7 @@ import ( "github.com/gravitational/teleport" "github.com/gravitational/teleport/api/types" apievents "github.com/gravitational/teleport/api/types/events" + "github.com/gravitational/teleport/lib/auth/recordingencryption" "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/events/filesessions" "github.com/gravitational/teleport/lib/services" @@ -91,6 +92,9 @@ type Config struct { // StartTime represents the time the recorder started. If not zero, this // value is used to generate the events index. StartTime time.Time + + // Encrypter wraps the final gzip writer with encryption. + Encrypter events.EncryptionWrapper } // New returns a [events.SessionPreparerRecorder]. If session recording is disabled, @@ -132,7 +136,10 @@ func New(cfg Config) (events.SessionPreparerRecorder, error) { cfg.DataDir, teleport.LogsDir, teleport.ComponentUpload, events.StreamingSessionsDir, cfg.Namespace, ) - fileStreamer, err := filesessions.NewStreamer(uploadDir) + if cfg.Encrypter == nil { + cfg.Encrypter = recordingencryption.NewEncryptionWrapper(cfg.RecordingCfg) + } + fileStreamer, err := filesessions.NewStreamer(uploadDir, cfg.Encrypter) if err != nil { return nil, trace.Wrap(err) } diff --git a/lib/events/session_writer_test.go b/lib/events/session_writer_test.go index c8345731352b8..6ad4b7464ffcf 100644 --- a/lib/events/session_writer_test.go +++ b/lib/events/session_writer_test.go @@ -74,7 +74,7 @@ func TestSessionWriter(t *testing.T) { require.NoError(t, err) for _, part := range parts { - reader := events.NewProtoReader(bytes.NewReader(part)) + reader := events.NewProtoReader(bytes.NewReader(part), nil) out, err := reader.ReadAll(test.ctx) require.NoError(t, err, "part crash %#v", part) outEvents = append(outEvents, out...) @@ -420,7 +420,7 @@ func (a *sessionWriterTest) collectEvents(t *testing.T) []apievents.AuditEvent { for _, part := range parts { readers = append(readers, bytes.NewReader(part)) } - reader := events.NewProtoReader(io.MultiReader(readers...)) + reader := events.NewProtoReader(io.MultiReader(readers...), nil) outEvents, err := reader.ReadAll(a.ctx) require.NoError(t, err, "failed to read") t.Logf("Reader stats :%v", reader.GetStats().ToFields()) diff --git a/lib/events/stream.go b/lib/events/stream.go index 172c690d6e319..6299ad77ae908 100644 --- a/lib/events/stream.go +++ b/lib/events/stream.go @@ -36,6 +36,7 @@ import ( apievents "github.com/gravitational/teleport/api/types/events" "github.com/gravitational/teleport/api/utils/retryutils" + "github.com/gravitational/teleport/lib/auth/recordingencryption" "github.com/gravitational/teleport/lib/auth/recordingmetadata" "github.com/gravitational/teleport/lib/auth/summarizer" "github.com/gravitational/teleport/lib/defaults" @@ -43,6 +44,16 @@ import ( "github.com/gravitational/teleport/lib/utils" ) +// ProtoStreamFlag is a bit flag containing options that were used to record the stream, such as whether or not the +// stream was encrypted. It appears in the header of v2+ proto streams and should be used to construct the correct +// ProtoReader configuration. +type ProtoStreamFlag = uint8 + +const ( + // ProtoStreamFlagEncrypted flags whether or not a stream was encrypted during recording. + ProtoStreamFlagEncrypted = 1 << iota +) + const ( // Int32Size is a constant for 32 bit integer byte size Int32Size = 4 @@ -64,6 +75,9 @@ const ( // ProtoStreamV1 is a version of the binary protocol ProtoStreamV1 = 1 + // ProtoStreamV2 is a version of the binary protocol + ProtoStreamV2 = 2 + // ProtoStreamV1PartHeaderSize is the size of the part of the protocol stream // on disk format, it consists of // * 8 bytes for the format version @@ -71,6 +85,14 @@ const ( // * 8 bytes for optional padding size at the end of the slice ProtoStreamV1PartHeaderSize = Int64Size * 3 + // ProtoStreamV2PartHeaderSize is the size of the part of the protocol stream + // on disk format, it consists of + // * 8 bytes for the format version + // * 8 bytes for meaningful size of the part + // * 8 bytes for optional padding size at the end of the slice + // * 8 bytes for 1 byte flags and 7 bytes of zero padding reserved for future + ProtoStreamV2PartHeaderSize = Int64Size * 4 + // ProtoStreamV1RecordHeaderSize is the size of the header // of the record header, it consists of the record length ProtoStreamV1RecordHeaderSize = Int32Size @@ -80,6 +102,16 @@ const ( uploaderReservePartErrorMessage = "uploader failed to reserve upload part" ) +// An EncryptionWrapper wraps a given io.WriteCloser with encryption. +type EncryptionWrapper interface { + WithEncryption(context.Context, io.WriteCloser) (io.WriteCloser, error) +} + +// A DecryptionWrapper wraps a given io.Reader with decryption. +type DecryptionWrapper interface { + WithDecryption(context.Context, io.Reader) (io.Reader, error) +} + // ProtoStreamerConfig specifies configuration for the part type ProtoStreamerConfig struct { Uploader MultipartUploader @@ -100,6 +132,8 @@ type ProtoStreamerConfig struct { SessionSummarizerProvider *summarizer.SessionSummarizerProvider // RecordingMetadataProvider is a provider of the recording metadata service. RecordingMetadataProvider *recordingmetadata.Provider + // Encrypter wraps the final gzip writer with encryption. + Encrypter EncryptionWrapper } // CheckAndSetDefaults checks and sets streamer defaults @@ -152,6 +186,7 @@ func (s *ProtoStreamer) CreateAuditStreamForUpload(ctx context.Context, sid sess RetryConfig: s.cfg.RetryConfig, SessionSummarizerProvider: s.cfg.SessionSummarizerProvider, RecordingMetadataProvider: s.cfg.RecordingMetadataProvider, + Encrypter: s.cfg.Encrypter, }) } @@ -183,6 +218,7 @@ func (s *ProtoStreamer) ResumeAuditStream(ctx context.Context, sid session.ID, u RetryConfig: s.cfg.RetryConfig, SessionSummarizerProvider: s.cfg.SessionSummarizerProvider, RecordingMetadataProvider: s.cfg.RecordingMetadataProvider, + Encrypter: s.cfg.Encrypter, }) } @@ -221,6 +257,8 @@ type ProtoStreamConfig struct { SessionSummarizerProvider *summarizer.SessionSummarizerProvider // RecordingMetadataProvider is a provider of the recording metadata service. RecordingMetadataProvider *recordingmetadata.Provider + // Encrypter wraps the final gzip writer with encryption. + Encrypter EncryptionWrapper } // CheckAndSetDefaults checks and sets default values @@ -315,6 +353,7 @@ func NewProtoStream(cfg ProtoStreamConfig) (*ProtoStream, error) { semUploads: make(chan struct{}, cfg.ConcurrentUploads), lastPartNumber: 0, retryConfig: *cfg.RetryConfig, + encrypter: cfg.Encrypter, } if len(cfg.CompletedParts) > 0 { // skip 2 extra parts as a protection from accidental overwrites. @@ -519,7 +558,7 @@ type sliceWriter struct { completedParts []StreamPart // emptyHeader is used to write empty header // to preserve some bytes - emptyHeader [ProtoStreamV1PartHeaderSize]byte + emptyHeader [ProtoStreamV2PartHeaderSize]byte // retryConfig defines how to retry on a failed upload retryConfig retryutils.LinearConfig // sshSessionEndEvent is an event that marked the end of this session if it was @@ -534,6 +573,8 @@ type sliceWriter struct { // point where the session end event has already been uploaded. If captured, // it will be passed to the summarizer. dbSessionEndEvent *apievents.DatabaseSessionEnd + // encrypter wraps writes with encryption + encrypter EncryptionWrapper } func (w *sliceWriter) updateCompletedParts(part StreamPart, lastEventIndex int64) { @@ -690,20 +731,43 @@ func (w *sliceWriter) newSlice() (*slice, error) { // This buffer will be returned to the pool by slice.Close buffer := w.proto.cfg.BufferPool.Get() buffer.Reset() + + var encrypted bool + var writer io.WriteCloser = &bufferCloser{Buffer: buffer} + if w.encrypter != nil { + // we want to encrypt after compression, so gzip needs to be the outermost layer + encryptedWriter, err := w.encrypter.WithEncryption(w.proto.completeCtx, writer) + switch { + case err == nil: + encrypted = true + writer = encryptedWriter + case errors.Is(err, recordingencryption.ErrEncryptionDisabled): + // if encryption isn't enabled, do nothing + default: + return nil, trace.Wrap(err, "fetching recording encrypter") + } + } + // reserve bytes for version header - buffer.Write(w.emptyHeader[:]) + headerSize := ProtoStreamV1PartHeaderSize + if encrypted { + headerSize = ProtoStreamV2PartHeaderSize + } + buffer.Write(w.emptyHeader[:headerSize]) err := w.proto.cfg.Uploader.ReserveUploadPart(w.proto.cancelCtx, w.proto.cfg.Upload, w.lastPartNumber) if err != nil { // Return the unused buffer to the pool. w.proto.cfg.BufferPool.Put(buffer) + writer.Close() return nil, trace.ConnectionProblem(err, uploaderReservePartErrorMessage) } return &slice{ - proto: w.proto, - buffer: buffer, - writer: newGzipWriter(&bufferCloser{Buffer: buffer}), + proto: w.proto, + buffer: buffer, + writer: newGzipWriter(writer), + encrypted: encrypted, }, nil } @@ -914,11 +978,12 @@ func (a *activeUpload) getPart() (*StreamPart, error) { // slice contains serialized protobuf messages type slice struct { proto *ProtoStream - writer *gzipWriter + writer io.WriteCloser buffer *bytes.Buffer isLast bool lastEventIndex int64 eventCount uint64 + encrypted bool } // reader returns a reader for the bytes written, no writes should be done after this @@ -939,11 +1004,23 @@ func (s *slice) reader() (io.ReadSeeker, error) { s.buffer.Write(padding) } data := s.buffer.Bytes() + + // TODO (eriktate): stop writing new recordings with ProtoStreamV1 in v19 + partHeader := PartHeader{ + ProtoVersion: ProtoStreamV1, + PartSize: uint64(wroteBytes - ProtoStreamV1PartHeaderSize), + PaddingSize: uint64(paddingBytes), + } + + if s.encrypted { + partHeader.ProtoVersion = ProtoStreamV2 + partHeader.PartSize = uint64(wroteBytes - ProtoStreamV2PartHeaderSize) + partHeader.Flags = ProtoStreamFlagEncrypted + } + // when the slice was created, the first bytes were reserved // for the protocol version number and size of the slice in bytes - binary.BigEndian.PutUint64(data[0:], ProtoStreamV1) - binary.BigEndian.PutUint64(data[Int64Size:], uint64(wroteBytes-ProtoStreamV1PartHeaderSize)) - binary.BigEndian.PutUint64(data[Int64Size*2:], uint64(paddingBytes)) + copy(data, partHeader.Bytes()) return bytes.NewReader(data), nil } @@ -1001,10 +1078,11 @@ func (s *slice) recordEvent(event protoEvent) error { } // NewProtoReader returns a new proto reader with slice pool -func NewProtoReader(r io.Reader) *ProtoReader { +func NewProtoReader(r io.Reader, decrypter DecryptionWrapper) *ProtoReader { return &ProtoReader{ reader: r, lastIndex: -1, + decrypter: decrypter, } } @@ -1039,6 +1117,7 @@ type ProtoReader struct { error error lastIndex int64 stats ProtoReaderStats + decrypter DecryptionWrapper } // ProtoReaderStats contains some reader statistics @@ -1101,6 +1180,65 @@ func (r *ProtoReader) GetStats() ProtoReaderStats { return r.stats } +// PartHeader is the structured representation of the binary header prepending each part of a ProtoStream output +type PartHeader struct { + ProtoVersion uint64 + PartSize uint64 + PaddingSize uint64 + Flags ProtoStreamFlag +} + +// Bytes returns the binary representation of a PartHeader formatted to be included in a ProtoStream +func (h PartHeader) Bytes() []byte { + var buf [ProtoStreamV2PartHeaderSize]byte + binary.BigEndian.PutUint64(buf[:], h.ProtoVersion) + binary.BigEndian.PutUint64(buf[Int64Size:], h.PartSize) + binary.BigEndian.PutUint64(buf[Int64Size*2:], h.PaddingSize) + if h.ProtoVersion == 1 { + return buf[:ProtoStreamV1PartHeaderSize] + } + binary.BigEndian.PutUint64(buf[Int64Size*3:], 0) + buf[Int64Size*3] = h.Flags + return buf[:] +} + +// ParsePartHeader parses a PartHeader from the given io.Reader +func ParsePartHeader(r io.Reader) (PartHeader, error) { + var header PartHeader + var buf [Int64Size]byte + if _, err := io.ReadFull(r, buf[:]); err != nil { + if errors.Is(err, io.EOF) { + return header, trace.Wrap(err) + } + return header, trace.ConvertSystemError(err) + } + + header.ProtoVersion = binary.BigEndian.Uint64(buf[:]) + if header.ProtoVersion > ProtoStreamV2 { + return PartHeader{}, trace.BadParameter("unsupported protocol version %v", header.ProtoVersion) + } + + // read size of this gzipped part as encoded by V1 protocol version + if _, err := io.ReadFull(r, buf[:]); err != nil { + return header, trace.ConvertSystemError(err) + } + header.PartSize = binary.BigEndian.Uint64(buf[:]) + // read padding size (could be 0) + if _, err := io.ReadFull(r, buf[:]); err != nil { + return header, trace.ConvertSystemError(err) + } + header.PaddingSize = binary.BigEndian.Uint64(buf[:]) + if header.ProtoVersion == 1 { + return header, nil + } + + if _, err := io.ReadFull(r, buf[:]); err != nil { + return header, trace.ConvertSystemError(err) + } + header.Flags = buf[0] + return header, nil +} + // Read returns next event or io.EOF in case of the end of the parts func (r *ProtoReader) Read(ctx context.Context) (apievents.AuditEvent, error) { // periodic checks of context after fixed amount of iterations @@ -1128,7 +1266,7 @@ func (r *ProtoReader) Read(ctx context.Context) (apievents.AuditEvent, error) { case protoReaderStateInit: // read the part header that consists of the protocol version // and the part size (for the V1 version of the protocol) - _, err := io.ReadFull(r.reader, r.sizeBytes[:Int64Size]) + header, err := ParsePartHeader(r.reader) if err != nil { // reached the end of the stream if errors.Is(err, io.EOF) { @@ -1137,26 +1275,25 @@ func (r *ProtoReader) Read(ctx context.Context) (apievents.AuditEvent, error) { } return nil, r.setError(trace.ConvertSystemError(err)) } - protocolVersion := binary.BigEndian.Uint64(r.sizeBytes[:Int64Size]) - if protocolVersion != ProtoStreamV1 { - return nil, trace.BadParameter("unsupported protocol version %v", protocolVersion) - } - // read size of this gzipped part as encoded by V1 protocol version - _, err = io.ReadFull(r.reader, r.sizeBytes[:Int64Size]) - if err != nil { - return nil, r.setError(trace.ConvertSystemError(err)) - } - partSize := binary.BigEndian.Uint64(r.sizeBytes[:Int64Size]) - // read padding size (could be 0) - _, err = io.ReadFull(r.reader, r.sizeBytes[:Int64Size]) - if err != nil { - return nil, r.setError(trace.ConvertSystemError(err)) + + r.padding = int64(header.PaddingSize) + reader := io.LimitReader(r.reader, int64(header.PartSize)) + if header.Flags&ProtoStreamFlagEncrypted != 0 { + if r.decrypter == nil { + return nil, r.setError(trace.Errorf("reading encrypted protos without decrypter")) + } + + reader, err = r.decrypter.WithDecryption(ctx, reader) + if err != nil { + return nil, r.setError(trace.Wrap(err)) + } } - r.padding = int64(binary.BigEndian.Uint64(r.sizeBytes[:Int64Size])) - gzipReader, err := newGzipReader(io.NopCloser(io.LimitReader(r.reader, int64(partSize)))) + + gzipReader, err := newGzipReader(io.NopCloser(reader)) if err != nil { return nil, r.setError(trace.Wrap(err)) } + r.gzipReader = gzipReader r.state = protoReaderStateCurrent continue @@ -1164,8 +1301,7 @@ func (r *ProtoReader) Read(ctx context.Context) (apievents.AuditEvent, error) { case protoReaderStateCurrent: // the record consists of length of the protobuf encoded // message and the message itself - _, err := io.ReadFull(r.gzipReader, r.sizeBytes[:Int32Size]) - if err != nil { + if _, err := io.ReadFull(r.gzipReader, r.sizeBytes[:Int32Size]); err != nil { if !errors.Is(err, io.EOF) { return nil, r.setError(trace.ConvertSystemError(err)) } @@ -1211,13 +1347,11 @@ func (r *ProtoReader) Read(ctx context.Context) (apievents.AuditEvent, error) { if messageSize == 0 { return nil, r.setError(trace.BadParameter("unexpected message size 0")) } - _, err = io.ReadFull(r.gzipReader, r.messageBytes[:messageSize]) - if err != nil { + if _, err := io.ReadFull(r.gzipReader, r.messageBytes[:messageSize]); err != nil { return nil, r.setError(trace.ConvertSystemError(err)) } oneof := apievents.OneOf{} - err = oneof.Unmarshal(r.messageBytes[:messageSize]) - if err != nil { + if err := oneof.Unmarshal(r.messageBytes[:messageSize]); err != nil { return nil, trace.Wrap(err) } event, err := apievents.FromOneOf(oneof) diff --git a/lib/events/stream_test.go b/lib/events/stream_test.go index 1c86344870196..048b8aafdfbf0 100644 --- a/lib/events/stream_test.go +++ b/lib/events/stream_test.go @@ -19,14 +19,18 @@ package events_test import ( + "bytes" "context" + "encoding/hex" "errors" + "io" "os" "strings" "testing" "time" "github.com/google/uuid" + "github.com/gravitational/trace" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -218,7 +222,7 @@ func TestReadCorruptedRecording(t *testing.T) { require.NoError(t, err) defer f.Close() - reader := events.NewProtoReader(f) + reader := events.NewProtoReader(f, nil) defer reader.Close() events, err := reader.ReadAll(ctx) @@ -471,6 +475,149 @@ func TestSummarization_Unknown(t *testing.T) { } } +func TestPartHeader(t *testing.T) { + cases := []struct { + name string + partHeader events.PartHeader + expectedErr error + expectedPartHeader *events.PartHeader // if different than starting part + }{ + { + name: "v1 part header", + partHeader: events.PartHeader{ + ProtoVersion: events.ProtoStreamV1, + PartSize: 1234, + PaddingSize: 4321, + Flags: events.ProtoStreamFlagEncrypted, + }, + expectedErr: nil, + expectedPartHeader: &events.PartHeader{ + ProtoVersion: events.ProtoStreamV1, + PartSize: 1234, + PaddingSize: 4321, + // no flags + }, + }, + { + name: "v2 part header encrypted", + partHeader: events.PartHeader{ + ProtoVersion: events.ProtoStreamV2, + PartSize: 1234, + PaddingSize: 4321, + Flags: events.ProtoStreamFlagEncrypted, + }, + expectedErr: nil, + expectedPartHeader: nil, + }, + { + name: "v2 part header unencrypted", + partHeader: events.PartHeader{ + ProtoVersion: events.ProtoStreamV2, + PartSize: 1234, + PaddingSize: 4321, + }, + expectedErr: nil, + expectedPartHeader: nil, + }, + { + name: "invalid version", + partHeader: events.PartHeader{ + ProtoVersion: 3, + PartSize: 1234, + PaddingSize: 4321, + Flags: events.ProtoStreamFlagEncrypted, + }, + expectedErr: trace.BadParameter("unsupported protocol version %v", 3), + expectedPartHeader: nil, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + buf := bytes.NewBuffer(c.partHeader.Bytes()) + switch c.partHeader.ProtoVersion { + case events.ProtoStreamV1: + require.Equal(t, events.ProtoStreamV1PartHeaderSize, buf.Len()) + case events.ProtoStreamV2: + require.Equal(t, events.ProtoStreamV2PartHeaderSize, buf.Len()) + } + + header, err := events.ParsePartHeader(buf) + if c.expectedErr != nil { + require.ErrorIs(t, err, c.expectedErr) + return + } + expected := c.partHeader + if c.expectedPartHeader != nil { + expected = *c.expectedPartHeader + } + require.Equal(t, expected, header) + }) + } +} + +func TestEncryptedRecordingIO(t *testing.T) { + ctx, cancel := context.WithTimeout(t.Context(), 10*time.Second) + defer cancel() + + uploader := eventstest.NewMemoryUploader() + encryptedIO := &fakeEncryptedIO{} + streamer, err := events.NewProtoStreamer(events.ProtoStreamerConfig{ + Uploader: uploader, + Encrypter: encryptedIO, + }) + require.NoError(t, err) + + const eventCount = 10 + evts := eventstest.GenerateTestSession(eventstest.SessionParams{PrintEvents: eventCount}) + sid := session.ID(evts[0].(events.SessionMetadataGetter).GetSessionID()) + stream, err := streamer.CreateAuditStream(ctx, sid) + require.NoError(t, err) + + preparer, err := events.NewPreparer(events.PreparerConfig{ + SessionID: sid, + Namespace: apidefaults.Namespace, + ClusterName: "cluster", + }) + require.NoError(t, err) + + for _, evt := range evts { + preparedEvent, err := preparer.PrepareSessionEvent(evt) + require.NoError(t, err) + + err = stream.RecordEvent(ctx, preparedEvent) + require.NoError(t, err) + } + + err = stream.Complete(ctx) + require.NoError(t, err) + + doneC := make(chan struct{}) + go func() { + defer close(doneC) + stream.Complete(ctx) + stream.Close(ctx) + }() + + select { + case <-ctx.Done(): + t.Fatal("Timeout waiting for emitter to complete") + case <-doneC: + } + + out := fakeWriterAt{ + buf: &bytes.Buffer{}, + } + err = uploader.Download(ctx, sid, out) + require.NoError(t, err) + + reader := events.NewProtoReader(out.buf, encryptedIO) + + decryptedEvents, err := reader.ReadAll(ctx) + require.NoError(t, err) + require.Len(t, decryptedEvents, eventCount+2) +} + func makeQueryEvent(id string, query string) *apievents.DatabaseSessionQuery { return &apievents.DatabaseSessionQuery{ Metadata: apievents.Metadata{ @@ -509,3 +656,47 @@ func (m *MockSummarizer) SummarizeWithoutEndEvent(ctx context.Context, sessionID args := m.Called(ctx, sessionID) return args.Error(0) } + +// encryptedIO is really just a reversible transform, so we fake encryption by encoding/decoding as hex +type fakeEncryptedIO struct { + err error +} + +type fakeEncrypter struct { + inner io.WriteCloser + writer io.Writer +} + +func (f *fakeEncrypter) Write(out []byte) (int, error) { + return f.writer.Write(out) +} + +func (f *fakeEncrypter) Close() error { + return f.inner.Close() +} + +func (f *fakeEncryptedIO) WithEncryption(ctx context.Context, writer io.WriteCloser) (io.WriteCloser, error) { + hexWriter := hex.NewEncoder(writer) + encrypter := &fakeEncrypter{ + inner: writer, + writer: hexWriter, + } + + return encrypter, f.err +} + +func (f *fakeEncryptedIO) WithDecryption(ctx context.Context, reader io.Reader) (io.Reader, error) { + return hex.NewDecoder(reader), f.err +} + +type fakeWriterAt struct { + buf *bytes.Buffer +} + +func (f fakeWriterAt) Write(p []byte) (int, error) { + return f.buf.Write(p) +} + +func (f fakeWriterAt) WriteAt(p []byte, offset int64) (int, error) { + return f.Write(p) +} diff --git a/lib/events/test/streamsuite.go b/lib/events/test/streamsuite.go index beaf7bce87cb0..83d746b861821 100644 --- a/lib/events/test/streamsuite.go +++ b/lib/events/test/streamsuite.go @@ -255,7 +255,8 @@ func StreamWithParameters(t *testing.T, handler events.MultipartHandler, params _, err = f.Seek(0, 0) require.NoError(t, err) - reader := events.NewProtoReader(f) + reader := events.NewProtoReader(f, nil) + out, err := reader.ReadAll(ctx) require.NoError(t, err) @@ -326,7 +327,8 @@ func StreamResumeWithParameters(t *testing.T, handler events.MultipartHandler, p _, err = f.Seek(0, 0) require.NoError(t, err) - reader := events.NewProtoReader(f) + reader := events.NewProtoReader(f, nil) + out, err := reader.ReadAll(ctx) require.NoError(t, err) diff --git a/lib/service/service.go b/lib/service/service.go index 9d3684e77ed91..203c6db2a7805 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -83,6 +83,7 @@ import ( "github.com/gravitational/teleport/api/utils/keys" "github.com/gravitational/teleport/api/utils/retryutils" apisshutils "github.com/gravitational/teleport/api/utils/sshutils" + "github.com/gravitational/teleport/entitlements" "github.com/gravitational/teleport/lib" "github.com/gravitational/teleport/lib/agentless" "github.com/gravitational/teleport/lib/auditd" @@ -90,7 +91,9 @@ import ( "github.com/gravitational/teleport/lib/auth/accesspoint" "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/auth/keygen" + "github.com/gravitational/teleport/lib/auth/keystore" "github.com/gravitational/teleport/lib/auth/machineid/machineidv1" + "github.com/gravitational/teleport/lib/auth/recordingencryption" "github.com/gravitational/teleport/lib/auth/recordingmetadata" "github.com/gravitational/teleport/lib/auth/recordingmetadata/recordingmetadatav1" "github.com/gravitational/teleport/lib/auth/state" @@ -2089,6 +2092,7 @@ func (process *TeleportProcess) initAuthExternalAuditLog(auditConfig types.Clust func (process *TeleportProcess) initAuthService() error { var err error cfg := process.Config + logger := process.logger.With(teleport.ComponentKey, teleport.Component(teleport.ComponentAuth, process.id)) // Initialize the storage back-ends for keys, events and records b, err := process.initAuthStorage() @@ -2097,10 +2101,88 @@ func (process *TeleportProcess) initAuthService() error { } process.backend = b + clusterName := cfg.Auth.ClusterName.GetClusterName() + ident, err := process.storage.ReadIdentity(state.IdentityCurrent, types.RoleAdmin) + if err != nil && !trace.IsNotFound(err) { + return trace.Wrap(err) + } + if ident != nil { + clusterName = ident.ClusterName + } + + cn, err := services.NewClusterNameWithRandomID(types.ClusterNameSpecV2{ + ClusterName: clusterName, + }) + + clusterConfig := cfg.ClusterConfiguration + if clusterConfig == nil { + clusterConfig, err = local.NewClusterConfigurationService(b) + if err != nil { + return trace.Wrap(err) + } + } + + // create keystore + keystoreOpts := &keystore.Options{ + HostUUID: cfg.HostUUID, + ClusterName: cn, + AuthPreferenceGetter: clusterConfig, + FIPS: cfg.FIPS, + } + + switch { + case cfg.Auth.KeyStore.PKCS11 != servicecfg.PKCS11Config{}: + if !modules.GetModules().Features().GetEntitlement(entitlements.HSM).Enabled { + return trace.Errorf("PKCS11 HSM support requires a license with the HSM feature enabled: %w", auth.ErrRequiresEnterprise) + } + case cfg.Auth.KeyStore.GCPKMS != servicecfg.GCPKMSConfig{}: + if !modules.GetModules().Features().GetEntitlement(entitlements.HSM).Enabled { + return trace.Errorf("GCP KMS support requires a license with the HSM feature enabled: %w", auth.ErrRequiresEnterprise) + } + case cfg.Auth.KeyStore.AWSKMS != nil: + if !modules.GetModules().Features().GetEntitlement(entitlements.HSM).Enabled { + return trace.Errorf("AWS KMS support requires a license with the HSM feature enabled: %w", auth.ErrRequiresEnterprise) + } + } + + keyStore, err := keystore.NewManager(process.GracefulExitContext(), &cfg.Auth.KeyStore, keystoreOpts) + if err != nil { + return trace.Wrap(err) + } + + localRecordingEncryption, err := local.NewRecordingEncryptionService(b) + if err != nil { + return trace.Wrap(err) + } + + recordingEncryptionManager, err := recordingencryption.NewManager(process.GracefulExitContext(), recordingencryption.ManagerConfig{ + Backend: localRecordingEncryption, + Cache: localRecordingEncryption, + KeyStore: keyStore, + Logger: logger, + ClusterConfig: clusterConfig, + LockConfig: backend.RunWhileLockedConfig{ + LockConfiguration: backend.LockConfiguration{ + Backend: process.backend, + TTL: time.Second * 30, + LockNameComponents: []string{"recording_encryption"}, + }, + }, + InitialSessionRecordingConfig: cfg.Auth.SessionRecordingConfig, + }) + if err != nil { + return trace.Wrap(err, "initializing session recording encryption") + } + + clusterConfig = recordingEncryptionManager var emitter apievents.Emitter var streamer events.Streamer var uploadHandler events.MultipartHandler var externalAuditStorage *externalauditstorage.Configurator + encryptedIO, err := recordingencryption.NewEncryptedIO(clusterConfig, recordingEncryptionManager) + if err != nil { + return trace.Wrap(err) + } sessionSummarizerProvider := summarizer.NewSessionSummarizerProvider() recordingMetadataProvider := recordingmetadata.NewProvider() @@ -2145,6 +2227,7 @@ func (process *TeleportProcess) initAuthService() error { Uploader: uploadHandler, SessionSummarizerProvider: sessionSummarizerProvider, RecordingMetadataProvider: recordingMetadataProvider, + Encrypter: encryptedIO, }) if err != nil { return trace.Wrap(err) @@ -2165,6 +2248,7 @@ func (process *TeleportProcess) initAuthService() error { ServerID: cfg.HostUUID, UploadHandler: uploadHandler, ExternalLog: externalLog, + Decrypter: encryptedIO, } auditServiceConfig.UID, auditServiceConfig.GID, err = adminCreds() if err != nil { @@ -2186,15 +2270,6 @@ func (process *TeleportProcess) initAuthService() error { } } - clusterName := cfg.Auth.ClusterName.GetClusterName() - ident, err := process.storage.ReadIdentity(state.IdentityCurrent, types.RoleAdmin) - if err != nil && !trace.IsNotFound(err) { - return trace.Wrap(err) - } - if ident != nil { - clusterName = ident.ClusterName - } - checkingEmitter, err := events.NewCheckingEmitter(events.CheckingEmitterConfig{ Inner: events.NewMultiEmitter(events.NewLoggingEmitter(process.GetClusterFeatures().Cloud), emitter), Clock: process.Clock, @@ -2220,14 +2295,6 @@ func (process *TeleportProcess) initAuthService() error { traceClt = clt } - cn, err := services.NewClusterNameWithRandomID(types.ClusterNameSpecV2{ - ClusterName: clusterName, - }) - if err != nil { - return trace.Wrap(err) - } - - logger := process.logger.With(teleport.ComponentKey, teleport.Component(teleport.ComponentAuth, process.id)) // Environment variable for disabling the check major version upgrade check and overrides // latest known version in backend. skipVersionCheckFromEnv := os.Getenv("TELEPORT_UNSTABLE_SKIP_VERSION_UPGRADE_CHECK") != "" @@ -2240,7 +2307,7 @@ func (process *TeleportProcess) initAuthService() error { VersionStorage: process.storage, SkipVersionCheck: cfg.SkipVersionCheck || skipVersionCheckFromEnv, Authority: cfg.Keygen, - ClusterConfiguration: cfg.ClusterConfiguration, + ClusterConfiguration: clusterConfig, AutoUpdateService: cfg.AutoUpdateService, ClusterAuditConfig: cfg.Auth.AuditConfig, ClusterNetworkingConfig: cfg.Auth.NetworkingConfig, @@ -2266,6 +2333,7 @@ func (process *TeleportProcess) initAuthService() error { OIDCConnectors: cfg.OIDCConnectors, AuditLog: process.auditLog, CipherSuites: cfg.CipherSuites, + KeyStore: keyStore, KeyStoreConfig: cfg.Auth.KeyStore, Emitter: checkingEmitter, Streamer: events.NewReportingStreamer(streamer, process.Config.Testing.UploadEventsC), @@ -2279,6 +2347,7 @@ func (process *TeleportProcess) initAuthService() error { Tracer: process.TracingProvider.Tracer(teleport.ComponentAuth), Logger: logger, SessionSummarizerProvider: sessionSummarizerProvider, + RecordingEncryption: recordingEncryptionManager, }, func(as *auth.Server) error { if !process.Config.CachePolicy.Enabled { return nil @@ -2294,6 +2363,7 @@ func (process *TeleportProcess) initAuthService() error { return trace.Wrap(err) } as.Cache = cache + recordingEncryptionManager.SetCache(cache) return nil }) @@ -2675,6 +2745,10 @@ func (process *TeleportProcess) initAuthService() error { })) }) + process.RegisterFunc("auth.recording_encryption_resolver", func() error { + return trace.Wrap(recordingEncryptionManager.Watch(process.GracefulExitContext(), authServer.Services)) + }) + // execute this when process is asked to exit: process.OnExit("auth.shutdown", func(payload any) { // The listeners have to be closed here, because if shutdown @@ -2783,6 +2857,7 @@ func (process *TeleportProcess) newAccessCacheForServices(cfg accesspoint.Config cfg.HealthCheckConfig = services.HealthCheckConfig cfg.BotInstance = services.BotInstance cfg.Plugin = services.Plugins + cfg.RecordingEncryption = services.RecordingEncryptionManager return accesspoint.NewCache(cfg) } @@ -3528,11 +3603,12 @@ func (process *TeleportProcess) initUploaderService() error { corruptedDir := filepath.Join(paths[1]...) fileUploader, err := filesessions.NewUploader(filesessions.UploaderConfig{ - Streamer: uploaderClient, - ScanDir: uploadsDir, - CorruptedDir: corruptedDir, - EventsC: process.Config.Testing.UploadEventsC, - InitialScanDelay: 15 * time.Second, + Streamer: uploaderClient, + ScanDir: uploadsDir, + CorruptedDir: corruptedDir, + EventsC: process.Config.Testing.UploadEventsC, + InitialScanDelay: 15 * time.Second, + EncryptedRecordingUploader: uploaderClient, }) if err != nil { return trace.Wrap(err) diff --git a/lib/services/local/events.go b/lib/services/local/events.go index fb61d73e2b387..e97f4b9058ab3 100644 --- a/lib/services/local/events.go +++ b/lib/services/local/events.go @@ -263,6 +263,10 @@ func (e *EventsService) NewWatcher(ctx context.Context, watch types.Watch) (type parser = newWorkloadIdentityX509RevocationParser() case types.KindHealthCheckConfig: parser = newHealthCheckConfigParser() + case types.KindRecordingEncryption: + parser = newRecordingEncryptionParser() + case types.KindRotatedKey: + parser = newRotatedKeyParser() default: if watch.AllowPartialSuccess { continue diff --git a/lib/services/local/recording_encryption.go b/lib/services/local/recording_encryption.go new file mode 100644 index 0000000000000..7d503f0876e5e --- /dev/null +++ b/lib/services/local/recording_encryption.go @@ -0,0 +1,219 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package local + +import ( + "context" + "crypto/x509" + + "github.com/gravitational/trace" + + headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1" + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/auth/recordingencryption" + "github.com/gravitational/teleport/lib/backend" + "github.com/gravitational/teleport/lib/services" + "github.com/gravitational/teleport/lib/services/local/generic" +) + +const ( + recordingEncryptionPrefix = "recording_encryption" + rotatedKeyPrefix = "recording_encryption_rotated" +) + +// RecordingEncryptionService exposes backend functionality for working with the +// cluster's RecordingEncryption resource. +type RecordingEncryptionService struct { + encryption *generic.ServiceWrapper[*recordingencryptionv1.RecordingEncryption] + rotatedKey *generic.ServiceWrapper[*recordingencryptionv1.RotatedKey] +} + +var _ services.RecordingEncryption = (*RecordingEncryptionService)(nil) + +// NewRecordingEncryptionService creates a new RecordingEncryptionService. +func NewRecordingEncryptionService(b backend.Backend) (*RecordingEncryptionService, error) { + const pageLimit = 100 + encryption, err := generic.NewServiceWrapper(generic.ServiceConfig[*recordingencryptionv1.RecordingEncryption]{ + Backend: b, + PageLimit: pageLimit, + ResourceKind: types.KindRecordingEncryption, + BackendPrefix: backend.NewKey(recordingEncryptionPrefix), + MarshalFunc: services.MarshalProtoResource[*recordingencryptionv1.RecordingEncryption], + UnmarshalFunc: services.UnmarshalProtoResource[*recordingencryptionv1.RecordingEncryption], + }) + if err != nil { + return nil, trace.Wrap(err) + } + + rotatedKey, err := generic.NewServiceWrapper(generic.ServiceConfig[*recordingencryptionv1.RotatedKey]{ + Backend: b, + PageLimit: pageLimit, + ResourceKind: types.KindRotatedKey, + BackendPrefix: backend.NewKey(rotatedKeyPrefix), + MarshalFunc: services.MarshalProtoResource[*recordingencryptionv1.RotatedKey], + UnmarshalFunc: services.UnmarshalProtoResource[*recordingencryptionv1.RotatedKey], + }) + if err != nil { + return nil, trace.Wrap(err) + } + + return &RecordingEncryptionService{ + encryption: encryption, + rotatedKey: rotatedKey, + }, nil +} + +// CreateRecordingEncryption creates a new RecordingEncryption in the backend. +func (s *RecordingEncryptionService) CreateRecordingEncryption(ctx context.Context, encryption *recordingencryptionv1.RecordingEncryption) (*recordingencryptionv1.RecordingEncryption, error) { + if encryption.Metadata == nil { + encryption.Metadata = &headerv1.Metadata{} + } + encryption.Metadata.Name = types.MetaNameRecordingEncryption + encryption.Kind = types.KindRecordingEncryption + created, err := s.encryption.CreateResource(ctx, encryption) + return created, trace.Wrap(err) +} + +// UpdateRecordingEncryption replaces the RecordingEncryption resource with the given one. +func (s *RecordingEncryptionService) UpdateRecordingEncryption(ctx context.Context, encryption *recordingencryptionv1.RecordingEncryption) (*recordingencryptionv1.RecordingEncryption, error) { + if encryption.Metadata == nil { + encryption.Metadata = &headerv1.Metadata{} + } + encryption.Metadata.Name = types.MetaNameRecordingEncryption + encryption.Kind = types.KindRecordingEncryption + updated, err := s.encryption.ConditionalUpdateResource(ctx, encryption) + return updated, trace.Wrap(err) +} + +// DeleteRecordingEncryption removes the RecordingEncryption from the cluster. +func (s *RecordingEncryptionService) DeleteRecordingEncryption(ctx context.Context) error { + return trace.Wrap(s.encryption.DeleteResource(ctx, types.MetaNameRecordingEncryption)) +} + +// GetRecordingEncryption retrieves the RecordingEncryption for the cluster. +func (s *RecordingEncryptionService) GetRecordingEncryption(ctx context.Context) (*recordingencryptionv1.RecordingEncryption, error) { + encryption, err := s.encryption.GetResource(ctx, types.MetaNameRecordingEncryption) + return encryption, trace.Wrap(err) +} + +// CreateRotatedKey creates a new RotatedKey in the backend keyed on the fingerprint of the given public key. +func (s *RecordingEncryptionService) CreateRotatedKey(ctx context.Context, key *types.EncryptionKeyPair) (*recordingencryptionv1.RotatedKey, error) { + parsed, err := x509.ParsePKIXPublicKey(key.PublicKey) + if err != nil { + return nil, trace.Wrap(err) + } + + fp, err := recordingencryption.Fingerprint(parsed) + if err != nil { + return nil, trace.Wrap(err) + } + created, err := s.rotatedKey.CreateResource(ctx, &recordingencryptionv1.RotatedKey{ + Metadata: &headerv1.Metadata{ + Name: fp, + }, + Kind: types.KindRotatedKey, + Spec: &recordingencryptionv1.RotatedKeySpec{ + EncryptionKeyPair: key, + }, + }) + return created, trace.Wrap(err) +} + +// GetRotatedKey retrieves the RotatedKey related to the given public key fingerprint from the backend. +func (s *RecordingEncryptionService) GetRotatedKey(ctx context.Context, fingerprint string) (*recordingencryptionv1.RotatedKey, error) { + rotatedKey, err := s.rotatedKey.GetResource(ctx, fingerprint) + return rotatedKey, trace.Wrap(err) +} + +// DeleteRotatedKey removes the RotatedKey related with the given public key fingerprint from the backend. +func (s *RecordingEncryptionService) DeleteRotatedKey(ctx context.Context, fingerprint string) error { + return trace.Wrap(s.rotatedKey.DeleteResource(ctx, fingerprint)) +} + +type recordingEncryptionParser struct { + baseParser +} + +func newRecordingEncryptionParser() *recordingEncryptionParser { + return &recordingEncryptionParser{ + baseParser: newBaseParser(backend.NewKey(recordingEncryptionPrefix)), + } +} + +func (p *recordingEncryptionParser) parse(event backend.Event) (types.Resource, error) { + switch event.Type { + case types.OpPut: + recordingEncryption, err := services.UnmarshalProtoResource[*recordingencryptionv1.RecordingEncryption]( + event.Item.Value, + services.WithExpires(event.Item.Expires), + services.WithRevision(event.Item.Revision), + ) + if err != nil { + return nil, trace.Wrap(err, "unmarshaling resource from event") + } + return types.Resource153ToLegacy(recordingEncryption), nil + case types.OpDelete: + return &types.ResourceHeader{ + Kind: types.KindRecordingEncryption, + Version: types.V1, + Metadata: types.Metadata{ + Name: types.MetaNameRecordingEncryption, + }, + }, nil + default: + return nil, trace.BadParameter("event %v is not supported", event.Type) + } +} + +type rotatedKeyParser struct { + baseParser +} + +func newRotatedKeyParser() *rotatedKeyParser { + return &rotatedKeyParser{ + baseParser: newBaseParser(backend.NewKey(rotatedKeyPrefix)), + } +} + +func (p *rotatedKeyParser) parse(event backend.Event) (types.Resource, error) { + switch event.Type { + case types.OpPut: + rotatedKey, err := services.UnmarshalProtoResource[*recordingencryptionv1.RotatedKey]( + event.Item.Value, + services.WithExpires(event.Item.Expires), + services.WithRevision(event.Item.Revision), + ) + if err != nil { + return nil, trace.Wrap(err, "unmarshaling resource from event") + } + + return types.Resource153ToLegacy(rotatedKey), nil + case types.OpDelete: + header, err := services.UnmarshalProtoResource[*headerv1.ResourceHeader]( + event.Item.Value, + services.WithExpires(event.Item.Expires), + services.WithRevision(event.Item.Revision), + ) + if err != nil { + return nil, trace.Wrap(err, "unmarshaling deleted resource header") + } + return types.Resource153ToLegacy(header), nil + default: + return nil, trace.BadParameter("event %v is not supported", event.Type) + } +} diff --git a/lib/services/local/recording_encryption_test.go b/lib/services/local/recording_encryption_test.go new file mode 100644 index 0000000000000..5cdcc75afc886 --- /dev/null +++ b/lib/services/local/recording_encryption_test.go @@ -0,0 +1,182 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package local + +import ( + "context" + "crypto/x509" + "testing" + + "github.com/stretchr/testify/require" + + pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/api/utils/keys" + "github.com/gravitational/teleport/lib/auth/recordingencryption" + "github.com/gravitational/teleport/lib/backend" + "github.com/gravitational/teleport/lib/backend/memory" +) + +func TestRecordingEncryption(t *testing.T) { + bk, err := memory.New(memory.Config{}) + require.NoError(t, err) + service, err := NewRecordingEncryptionService(backend.NewSanitizer(bk)) + require.NoError(t, err) + + ctx := context.Background() + + initialEncryption := pb.RecordingEncryption{ + Spec: &pb.RecordingEncryptionSpec{ + ActiveKeyPairs: nil, + }, + } + + // get should fail when there's no recording encryption + _, err = service.GetRecordingEncryption(ctx) + require.Error(t, err) + + created, err := service.CreateRecordingEncryption(ctx, &initialEncryption) + require.NoError(t, err) + + encryption, err := service.GetRecordingEncryption(ctx) + require.NoError(t, err) + + require.Empty(t, created.Spec.ActiveKeyPairs) + require.Empty(t, encryption.Spec.ActiveKeyPairs) + + encryption.Spec.ActiveKeyPairs = []*pb.KeyPair{ + { + KeyPair: &types.EncryptionKeyPair{ + PrivateKey: []byte("recording encryption private"), + PublicKey: []byte("recording encryption public"), + Hash: 0, + }, + }, + } + + updated, err := service.UpdateRecordingEncryption(ctx, encryption) + require.NoError(t, err) + require.Len(t, updated.Spec.ActiveKeyPairs, 1) + require.EqualExportedValues(t, encryption.Spec.ActiveKeyPairs[0], updated.Spec.ActiveKeyPairs[0]) + + encryption, err = service.GetRecordingEncryption(ctx) + require.NoError(t, err) + require.Len(t, encryption.Spec.ActiveKeyPairs, 1) + require.EqualExportedValues(t, updated.Spec.ActiveKeyPairs[0], encryption.Spec.ActiveKeyPairs[0]) + + err = service.DeleteRecordingEncryption(ctx) + require.NoError(t, err) + _, err = service.GetRecordingEncryption(ctx) + require.Error(t, err) +} + +func TestRotatedKeys(t *testing.T) { + bk, err := memory.New(memory.Config{}) + require.NoError(t, err) + service, err := NewRecordingEncryptionService(backend.NewSanitizer(bk)) + require.NoError(t, err) + + ctx := context.Background() + + privateKey, err := keys.ParsePrivateKey(testRSA4096PrivateKeyPEM) + require.NoError(t, err) + publicKey := privateKey.Public() + + fingerprint, err := recordingencryption.Fingerprint(publicKey) + require.NoError(t, err) + + publicKeyDER, err := x509.MarshalPKIXPublicKey(publicKey) + require.NoError(t, err) + + // get should fail when there's no rotated key + _, err = service.GetRotatedKey(ctx, fingerprint) + require.Error(t, err) + + created, err := service.CreateRotatedKey(ctx, &types.EncryptionKeyPair{ + PrivateKey: testRSA4096PrivateKeyPEM, + PublicKey: publicKeyDER, + PrivateKeyType: types.PrivateKeyType_RAW, + }) + require.NoError(t, err) + require.Equal(t, testRSA4096PrivateKeyPEM, created.Spec.EncryptionKeyPair.PrivateKey) + require.Equal(t, publicKeyDER, created.Spec.EncryptionKeyPair.PublicKey) + require.Equal(t, types.PrivateKeyType_RAW, created.Spec.EncryptionKeyPair.PrivateKeyType) + + rotatedKey, err := service.GetRotatedKey(ctx, fingerprint) + require.NoError(t, err) + + require.Equal(t, testRSA4096PrivateKeyPEM, rotatedKey.Spec.EncryptionKeyPair.PrivateKey) + require.Equal(t, publicKeyDER, rotatedKey.Spec.EncryptionKeyPair.PublicKey) + require.Equal(t, types.PrivateKeyType_RAW, rotatedKey.Spec.EncryptionKeyPair.PrivateKeyType) + + err = service.DeleteRotatedKey(ctx, fingerprint) + require.NoError(t, err) + _, err = service.GetRotatedKey(ctx, fingerprint) + require.Error(t, err) +} + +var testRSA4096PrivateKeyPEM = []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIJKQIBAAKCAgEAwkUne5dEkxnKL825MRCoz2SjGTiD8Xat8mZSrD1N8XiEf0yE +ocNwdQ3JuJFruIyzrHiMWEuutW2bN/vG6CxET6QUT0WUN67xBnjT4rt/Xbf5W7vI +fHdmxvFZYVmboTQW4jFxAJt1AnzKDqPakLdLx7wsbs96z47aagS94Vhh0tGq5QsJ +HbfLVLK7DbEmKbgmYX3Lw7rg89xwDC638O+h/pmPyZbVYvFD7aCbuq4L8otaXt8s +YqJXAjx4Wmk4bQxz3HXKZ+2YRobRP18aSt+AT7/vswN1dpLIL0XmpDv9Ic4tmHmR +nF0jcfzWuGt4iJ1Ru3M0xBAPnKW56Q5MA6V2t3peOpNM0xbaZ4mzn85Uyg3z2sFu +YKvCmg+UDvzVpewmuxKR41slGfEm5a42CCv7rt7w+0lRLG4aFsD6Hy4il4Ur1HHW +KOKxZX8bdvhhybW5hQKVeqcGVOCqKK5bsuhEd3CQzlCjU4G01/z+5nL2EXKFQZsU +Uo8qIwDF9Zt6yPfW32nU54UMBVCx51o/RavqvRJ4+SOF7HmY0BXuXrBYShDWtbbc +jmNBSEyfiSnmbxwVQfgJ09L2xVWXRLf0wz2JaLxQ5WaOgaw8XKci9hkNoZVXcq7d +4rqRcpEfALxXabRQqtt8aMu8clcGWfjdtxZ5vGwAzOm9V7+Mz3j4ysUUm58CAwEA +AQKCAgB0ksa0dPrjQlB/CvWbqaGCgaMVGUKjfFG46Qmm7Up+IZFwSdw0rXAn7VQk +eq6nGVcfoV6mBRQbLmA74ctjulxrZcwCHYBpQYLEHXEX1ucAt8rb7vzJI2T68Axw +TDMFMpqgtIZYlPBLw9IDovMeb777ZcFL5RiOv+v0PlAqjrx0ovfnZQ3dVVKfynhQ +KQL7edMeITxKgTNHYfmidc5Ot5z/h+ouT2JQcvIN/5gzFwl4S4K49zZNIZkQcHTP +29/OH/DOU6hXYM1FVNTvMAQ49ZCrSkNtqh+sPTv+kfVqi8zDolLd8eUcbQ898Thv +hZ3YbH6E+waot/KGTzQV00xty7ZGK3Lb7c4CmTcX80lb2YFemxwkIXRwC3uqmr/y +gajyLGnFE8Pu92WAP2fiPEfwqXtekew3TtBC+psFRQF+Y15myfyhndNR/qtFPSvB +ooWeZQVUU/o0solCE6q/b1uyQxpZK/Z/GJewmtI3tfkDmTGADCeH4O+sPNtmO6xN +GSmctHPQyE+u2lNp+WCGVS+vbwFct9guMQEvVM5CBU1/mmOKeaNJOl4N6mj7GuqN +R5tQ1suOLlzsAOeCrVDTdpiQfx2UfDNKPk9wv2yu/tTBbOwHfxEUT+EiUrEXKrUI +n5DR14HJ+qnQNOk5sZUJ7G4ISZO0voSXeJJOguMGwaXajjbK8QKCAQEA4P39m4k2 +uv1LAspsELKvfJEaGdNaUAiHeQGK2co/S53p11/gx7D+EX7yJtVfp/nka/kZruzt +PiIb4nNIkY2giEMVoGYqOWQsLWUbIH70apqUBi+h1qs7RuIW+JaAE3e45gq/dguv ++w2CSNS+lcV/3laFDP80npg1y/RgKuacke+1Bfu0O/qrrJOTAh7cvbWiBQyRsDqQ +yhVb9L49fjhSSNHajU97ybKPXQ9w7zcFrpSaz5Or4mBl027vscJ3i2euabPINGmj +bSe32QUO1UzW8YTNGYlVZrfUYz7AvSZ1tr/Kf7/drf1kIBx/WiyyaDCyMqS4Slwb +ZjVoxKidFjtfpQKCAQEA3QtAcI7rMjrRO8SBkKFcZ14LY3iyLO/k5oVOa+ePQ8WR +rHUUxLdAixgnlEdUVgxjZG78zpAi8VUbvjUooMuHKXcaEWVEmfuNz+PAiImu/HxS +EBsPKjqZgpNcDMwnQ8yMFsiX2YUGuvXMkcaZbkHqWOHOCXhUeXVG4HZxboEMgArh ++bYhruP9G3NpuVRDFCQGq1RiFCPKQlyZMtvCGl694GE5EsWWglaPWkJGzGuT9hlq +fQCQB+UunYO1xmNpIn0MX0vKySu8SUdMp3NtDcqUVDf3t2EqoPe4OCJJ4z4D7+Xi +HO6wOs8raWXajumLMxU/LCLmR291eGHy/yuvDlzq8wKCAQEAxFYgx2e38Pk0Sh0m +rHOhm8xrwHmlaA3pWnk0F9Xb4jrNYvryBpC3RcFHwweUT9tLr8VS2kk6xmuxda0w +eIPkwMP5zV0aH7cAriR6xaLD23tFDRjn25LVSYfmj8uVvGdPXL+oUHTmfuhM9w1f +uwb8DKPnu23BF1ywJWj9urI/k0Jg7/W0VFrtEM4/DSytaIdl+Y38XJLe4to8wph4 +xPqVI6KtW38vANXnMUhWPwn+1VgsuFOfPQ7uDNHULYUMGQTDOM6AOOyuhoSQdLtr +NEu3jk9bQ5uKgPaOSoTqYKV9N5qqNUzTQA/NHhCAOcqjbTSBbJw9jfZOmqSk5mhV +nJ73WQKCAQEA0CnGd7m/+L+3R4fZVHEBaj8Ajp6dfQA2Gnkzzx50pqgqdbSU6GSD +HfqTW2qJG7fy6iQzY/wNTCSQSeIZ7sN8+Cm3nOY3YqOpezvKl0rCRfh198Dj2Sry +YiuQJmUkHQ9GZjZl+mzyV6MfEbFr0I+2uBl+RSDSvMcbBkvEqwJQ2UxmXxmMQv1l +4TIhQGz/9rmupi6DZuAFm9VEWMbn1pmeSu6EJw94nCoUOjXsIpq07rAkvq+G9Eh6 +S9A7oScBXX9R5XSk9ip/2KqSn6dt7ez3HxDN8h5JXOmszQBNgPloD8X32LNXtype +gZVv6+I4OtUpdtEu99sZT1M+2dszsl0CzQKCAQAHfAGLuGg9cwCbcH41H9HHj2du +/B+C20AZzUHZVDjYaKWJVZuxVZrWaogsPrarmxgbXrnsQwINugVtA/+OETQ466D6 +Re6osCSpPeQtHLJBrVkcp+Wqv2oWbiSeyNQduZLQ01Kp698p6Ytw5Ns0x40hVBKq +vaN6ewsznUZWAzmscJweTOTQTrks46eTJy0jckd/0CHcqrVV9c5UuSMy1StXpBsm +dWw2AGVtikZzY/BI4g/d2efNM0Yg+QTuehqBmQr6UX+mmT74egolafEkI52g6Vg+ +Xf6bcJnKeYqP0rVR377Ge6riSt1cyNwNFMY9VCWjk2YFK2PfT65+QXMI7yTi +-----END RSA PRIVATE KEY-----`) diff --git a/lib/services/recording_encryption.go b/lib/services/recording_encryption.go new file mode 100644 index 0000000000000..5ddeb0b7bb442 --- /dev/null +++ b/lib/services/recording_encryption.go @@ -0,0 +1,44 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package services + +import ( + "context" + + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/api/types" +) + +// RecordingEncryption handles CRUD operations for the RecordingEncryption resource. +type RecordingEncryption interface { + // CreateRecordingEncryption creates a new RecordingEncryption in the backend if one + // does not already exist. + CreateRecordingEncryption(ctx context.Context, encryption *recordingencryptionv1.RecordingEncryption) (*recordingencryptionv1.RecordingEncryption, error) + // UpdateRecordingEncryption replaces the RecordingEncryption resource with the given one. + UpdateRecordingEncryption(ctx context.Context, encryption *recordingencryptionv1.RecordingEncryption) (*recordingencryptionv1.RecordingEncryption, error) + // DeleteRecordingEncryption removes the RecordingEncryption from the cluster. + DeleteRecordingEncryption(ctx context.Context) error + // GetRecordingEncryption retrieves the RecordingEncryption for the cluster. + GetRecordingEncryption(ctx context.Context) (*recordingencryptionv1.RecordingEncryption, error) + + // CreateRotatedKey creates a new RotatedKey in the backend. + CreateRotatedKey(ctx context.Context, key *types.EncryptionKeyPair) (*recordingencryptionv1.RotatedKey, error) + // GetRotatedKey retrieves the RotatedKey related to the given fingerprint. + GetRotatedKey(ctx context.Context, fingerprint string) (*recordingencryptionv1.RotatedKey, error) + // DeleteRotatedKey retrieves the RotatedKey related to the given fingerprint. + DeleteRotatedKey(ctx context.Context, fingerprint string) error +} diff --git a/lib/services/sessionrecording.go b/lib/services/sessionrecording.go index 496bf02716276..c808d1048f575 100644 --- a/lib/services/sessionrecording.go +++ b/lib/services/sessionrecording.go @@ -19,6 +19,9 @@ package services import ( + "slices" + "strings" + "github.com/gravitational/trace" "github.com/gravitational/teleport/api/types" @@ -86,3 +89,60 @@ func MarshalSessionRecordingConfig(recConfig types.SessionRecordingConfig, opts return nil, trace.BadParameter("unrecognized session recording config version %T", recConfig) } } + +const ( + KeyTypeAWS = "aws_kms" + KeyTypeGCP = "gcp_kms" + KeyTypePKCS11 = "pkcs11" + KeyTypeSoftware = "software" +) + +var errRecordingEncryptionWithFIPS = &trace.BadParameterError{Message: `non-FIPS compliant session recording setting: "encryption" must not be enabled`} +var errManualKeyManagementInCloud = &trace.BadParameterError{Message: `"manual_key_management" configuration is unsupported in Teleport Cloud`} + +// ValidateSessionRecordingConfig checks that the state of a [SessionRecordingConfig] meets constraints. +func ValidateSessionRecordingConfig(cfg types.SessionRecordingConfig, fips, cloud bool) error { + if !slices.Contains(types.SessionRecordingModes, cfg.GetMode()) { + return trace.BadParameter("session recording mode must be one of %v; got %q", strings.Join(types.SessionRecordingModes, ","), cfg.GetMode()) + } + + encryptionCfg := cfg.GetEncryptionConfig() + if encryptionCfg == nil || !encryptionCfg.Enabled { + return nil + } + + if fips && encryptionCfg.Enabled { + return trace.Wrap(errRecordingEncryptionWithFIPS) + } + + manualKeyManagement := encryptionCfg.ManualKeyManagement + if manualKeyManagement == nil || !manualKeyManagement.Enabled { + return nil + } + + if cloud { + return trace.Wrap(errManualKeyManagementInCloud) + } + + if len(manualKeyManagement.ActiveKeys) == 0 { + return trace.BadParameter("at least one active key must be configured when using manually managed encryption keys") + } + + for _, label := range manualKeyManagement.ActiveKeys { + switch strings.ToLower(label.Type) { + case KeyTypeAWS, KeyTypeGCP, KeyTypePKCS11, KeyTypeSoftware: + default: + return trace.BadParameter("invalid key type %q found for active manually managed key", label.Type) + } + } + + for _, label := range manualKeyManagement.RotatedKeys { + switch strings.ToLower(label.Type) { + case KeyTypeAWS, KeyTypeGCP, KeyTypePKCS11, KeyTypeSoftware: + default: + return trace.BadParameter("invalid key type %q found for rotated manually managed key", label.Type) + } + } + + return nil +} diff --git a/lib/services/sessionrecording_test.go b/lib/services/sessionrecording_test.go new file mode 100644 index 0000000000000..afbc5f48ebdb4 --- /dev/null +++ b/lib/services/sessionrecording_test.go @@ -0,0 +1,178 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package services_test + +import ( + "strings" + "testing" + + "github.com/gravitational/trace" + "github.com/stretchr/testify/require" + + "github.com/gravitational/teleport/api/types" + "github.com/gravitational/teleport/lib/services" +) + +func TestValidateSessionRecordingConfig(t *testing.T) { + cases := []struct { + name string + spec types.SessionRecordingConfigSpecV2 + params types.SignatureAlgorithmSuiteParams + cloud bool + fips bool + expectErr error + }{ + { + name: "valid config", + spec: types.SessionRecordingConfigSpecV2{ + Mode: "node", + }, + fips: true, + cloud: true, + expectErr: nil, + }, + { + name: "valid config: encryption", + spec: types.SessionRecordingConfigSpecV2{ + Mode: "node", + Encryption: &types.SessionRecordingEncryptionConfig{ + Enabled: true, + }, + }, + expectErr: nil, + }, + { + name: "valid config: manual encryption", + spec: types.SessionRecordingConfigSpecV2{ + Mode: "node", + Encryption: &types.SessionRecordingEncryptionConfig{ + Enabled: true, + ManualKeyManagement: &types.ManualKeyManagementConfig{ + Enabled: true, + ActiveKeys: []*types.KeyLabel{ + { + Type: "aws_kms", + Label: "test", + }, + }, + }, + }, + }, + expectErr: nil, + }, + { + name: "invalid config: session mode", + spec: types.SessionRecordingConfigSpecV2{ + Mode: "invalid", + }, + expectErr: trace.BadParameter("session recording mode must be one of %v; got %q", strings.Join(types.SessionRecordingModes, ","), "invalid"), + }, + { + name: "invalid config: encryption with FIPS", + spec: types.SessionRecordingConfigSpecV2{ + Mode: "node", + Encryption: &types.SessionRecordingEncryptionConfig{ + Enabled: true, + }, + }, + fips: true, + expectErr: trace.BadParameter("non-FIPS compliant session recording setting"), + }, + { + name: "invalid config: manual encryption in cloud", + spec: types.SessionRecordingConfigSpecV2{ + Mode: "node", + Encryption: &types.SessionRecordingEncryptionConfig{ + Enabled: true, + ManualKeyManagement: &types.ManualKeyManagementConfig{ + Enabled: true, + }, + }, + }, + cloud: true, + expectErr: trace.BadParameter(`"manual_key_management" configuration is unsupported in Teleport Cloud`), + }, + { + name: "invalid config: manual encryption without active keys", + spec: types.SessionRecordingConfigSpecV2{ + Mode: "node", + Encryption: &types.SessionRecordingEncryptionConfig{ + Enabled: true, + ManualKeyManagement: &types.ManualKeyManagementConfig{ + Enabled: true, + }, + }, + }, + expectErr: trace.BadParameter("at least one active key must be configured when using manually managed encryption keys"), + }, + { + name: "invalid config: invalid manual key type", + spec: types.SessionRecordingConfigSpecV2{ + Mode: "node", + Encryption: &types.SessionRecordingEncryptionConfig{ + Enabled: true, + ManualKeyManagement: &types.ManualKeyManagementConfig{ + Enabled: true, + ActiveKeys: []*types.KeyLabel{ + { + Type: "unsupported", + Label: "test", + }, + }, + }, + }, + }, + expectErr: trace.BadParameter("invalid key type \"unsupported\" found for active manually managed key"), + }, + { + name: "invalid config: invalid manual rotated key type", + spec: types.SessionRecordingConfigSpecV2{ + Mode: "node", + Encryption: &types.SessionRecordingEncryptionConfig{ + Enabled: true, + ManualKeyManagement: &types.ManualKeyManagementConfig{ + Enabled: true, + ActiveKeys: []*types.KeyLabel{ + { + Type: "pkcs11", + Label: "test", + }, + }, + RotatedKeys: []*types.KeyLabel{ + { + Type: "unsupported", + Label: "test", + }, + }, + }, + }, + }, + expectErr: trace.BadParameter("invalid key type \"unsupported\" found for rotated manually managed key"), + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + err := services.ValidateSessionRecordingConfig(&types.SessionRecordingConfigV2{Spec: c.spec}, c.fips, c.cloud) + if c.expectErr == nil { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, c.expectErr.Error()) + } + }) + } +} diff --git a/lib/srv/app/server_test.go b/lib/srv/app/server_test.go index 59b86b9f3e488..7bf38a3a4ca0e 100644 --- a/lib/srv/app/server_test.go +++ b/lib/srv/app/server_test.go @@ -171,6 +171,7 @@ func SetUpSuite(t *testing.T) *Suite { func SetUpSuiteWithConfig(t *testing.T, config suiteConfig) *Suite { s := &Suite{} + s.closeContext, s.closeFunc = context.WithCancel(t.Context()) s.clock = clockwork.NewFakeClock() s.dataDir = t.TempDir() @@ -238,8 +239,6 @@ func SetUpSuiteWithConfig(t *testing.T, config suiteConfig) *Suite { s.user, err = authtest.CreateUser(context.Background(), s.tlsServer.Auth(), "foo", s.role) require.NoError(t, err) - s.closeContext, s.closeFunc = context.WithCancel(context.Background()) - // Create a in-memory HTTP server that will respond with a UUID. This value // will be checked in the client later to ensure a connection was made. s.message = uuid.New().String() diff --git a/tool/tctl/common/recordings_command.go b/tool/tctl/common/recordings_command.go index f2a2fdae8dfed..f354451bf6262 100644 --- a/tool/tctl/common/recordings_command.go +++ b/tool/tctl/common/recordings_command.go @@ -21,6 +21,7 @@ package common import ( "context" "fmt" + "io" "os" "github.com/alecthomas/kingpin/v2" @@ -47,6 +48,8 @@ type RecordingsCommand struct { format string // recordingsList implements the "tctl recordings ls" subcommand. recordingsList *kingpin.CmdClause + // recordingsEncryption implements the "tctl recordings encryption" subcommand. + recordingsEncryption recordingsEncryptionCommand // fromUTC is the start time to use for the range of recordings listed by the recorded session listing command fromUTC string // toUTC is the start time to use for the range of recordings listed by the recorded session listing command @@ -55,10 +58,17 @@ type RecordingsCommand struct { maxRecordingsToShow int // recordingsSince is a duration which sets the time into the past in which to list session recordings recordingsSince string + + // stdout allows to switch standard output source for resource command. Used in tests. + stdout io.Writer } // Initialize allows RecordingsCommand to plug itself into the CLI parser func (c *RecordingsCommand) Initialize(app *kingpin.Application, _ *tctlcfg.GlobalCLIFlags, config *servicecfg.Config) { + if c.stdout == nil { + c.stdout = os.Stdout + } + c.config = config recordings := app.Command("recordings", "View and control session recordings.") c.recordingsList = recordings.Command("ls", "List recorded sessions.") @@ -67,6 +77,11 @@ func (c *RecordingsCommand) Initialize(app *kingpin.Application, _ *tctlcfg.Glob c.recordingsList.Flag("to-utc", fmt.Sprintf("End of time range in which recordings are listed. Format %s. Defaults to current time.", defaults.TshTctlSessionListTimeFormat)).StringVar(&c.toUTC) c.recordingsList.Flag("limit", fmt.Sprintf("Maximum number of recordings to show. Default %s.", defaults.TshTctlSessionListLimit)).Default(defaults.TshTctlSessionListLimit).IntVar(&c.maxRecordingsToShow) c.recordingsList.Flag("last", "Duration into the past from which session recordings should be listed. Format 5h30m40s").StringVar(&c.recordingsSince) + c.recordingsEncryption.Initialize(recordings, c.stdout) + + if c.recordingsEncryption.stdout == nil { + c.recordingsEncryption.stdout = c.stdout + } } // TryRun attempts to run subcommands like "recordings ls". @@ -76,7 +91,7 @@ func (c *RecordingsCommand) TryRun(ctx context.Context, cmd string, clientFunc c case c.recordingsList.FullCommand(): commandFunc = c.ListRecordings default: - return false, nil + return c.recordingsEncryption.TryRun(ctx, cmd, clientFunc) } client, closeFn, err := clientFunc(ctx) if err != nil { @@ -103,5 +118,5 @@ func (c *RecordingsCommand) ListRecordings(ctx context.Context, tc *authclient.C if err != nil { return trace.Errorf("getting session events: %v", err) } - return trace.Wrap(common.ShowSessions(recordings, c.format, os.Stdout)) + return trace.Wrap(common.ShowSessions(recordings, c.format, c.stdout)) } diff --git a/tool/tctl/common/recordings_encryption_command.go b/tool/tctl/common/recordings_encryption_command.go new file mode 100644 index 0000000000000..6f9290d745ad9 --- /dev/null +++ b/tool/tctl/common/recordings_encryption_command.go @@ -0,0 +1,207 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package common + +import ( + "context" + "encoding/json" + "fmt" + "io" + "os" + + "github.com/alecthomas/kingpin/v2" + "github.com/gravitational/trace" + + "github.com/gravitational/teleport" + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/lib/asciitable" + "github.com/gravitational/teleport/lib/auth/authclient" + "github.com/gravitational/teleport/lib/defaults" + "github.com/gravitational/teleport/lib/utils" + commonclient "github.com/gravitational/teleport/tool/tctl/common/client" +) + +type recordingsEncryptionCommand struct { + // cmd implements the "tctl recordings encryptino" parent command + cmd *kingpin.CmdClause + + // rotateCmd implements the "tctl recordings encryption rotate" subcommand. + rotateCmd *kingpin.CmdClause + + // statusCmd implements the "tctl recordings encryption status" subcommand. + statusCmd *kingpin.CmdClause + + // completeCmd implements the "tctl recordings encryption complete" subcommand. + completeCmd *kingpin.CmdClause + + // rollbackCmd implements the "tctl recordings encryption rollback" subcommand. + rollbackCmd *kingpin.CmdClause + + // format is the output format of statusCmd (text, json, or yaml) + format string + + // stdout allows for redirecting command output. Useful for tests. + stdout io.Writer +} + +// Initialize allows recordingsEncryptionCommand to plug itself into the CLI parser. +func (c *recordingsEncryptionCommand) Initialize(recordingsCmd *kingpin.CmdClause, stdout io.Writer) { + c.cmd = recordingsCmd.Command("encryption", "Manage encryption properties of session recordings.") + + c.rotateCmd = c.cmd.Command("rotate", "Rotate encryption keys used for encrypting session recordings.") + c.statusCmd = c.cmd.Command("status", "Show current rotation status.") + c.statusCmd.Flag("format", defaults.FormatFlagDescription(defaults.DefaultFormats...)+". Defaults to 'text'.").Default(teleport.Text).StringVar(&c.format) + c.completeCmd = c.cmd.Command("complete-rotation", "Completes an in-progress encryption key rotation.") + c.rollbackCmd = c.cmd.Command("rollback-rotation", "Rolls back an in-progress encryption key rotation.") + if stdout == nil { + c.stdout = os.Stdout + } +} + +// TryRun attempts to run subcommands like "recordings encryption rotate". +func (c *recordingsEncryptionCommand) TryRun(ctx context.Context, cmd string, clientFunc commonclient.InitFunc) (match bool, err error) { + var commandFunc func(ctx context.Context, client *authclient.Client) error + switch cmd { + case c.rotateCmd.FullCommand(): + commandFunc = c.Rotate + case c.statusCmd.FullCommand(): + commandFunc = c.Status + case c.completeCmd.FullCommand(): + commandFunc = c.Complete + case c.rollbackCmd.FullCommand(): + commandFunc = c.Rollback + default: + return false, nil + } + client, closeFn, err := clientFunc(ctx) + if err != nil { + return false, trace.Wrap(err) + } + err = commandFunc(ctx, client) + closeFn(ctx) + + return true, trace.Wrap(err) +} + +// Rotate initiates a key rotation. It should fail if a key rotation is already +// in progress. +func (c *recordingsEncryptionCommand) Rotate(ctx context.Context, tc *authclient.Client) error { + client := tc.RecordingEncryptionServiceClient() + if _, err := client.RotateKey(ctx, &recordingencryptionv1.RotateKeyRequest{}); err != nil { + return trace.Errorf("rotating key encryption keys: %v", err) + } + fmt.Fprintln(c.stdout, "Rotation started") + return nil +} + +// Complete an in progress key rotation. It should fail if any key is marked +// 'inaccessible'. +func (c *recordingsEncryptionCommand) Complete(ctx context.Context, tc *authclient.Client) error { + client := tc.RecordingEncryptionServiceClient() + if _, err := client.CompleteRotation(ctx, &recordingencryptionv1.CompleteRotationRequest{}); err != nil { + return trace.Errorf("completing encryption key rotation: %v", err) + } + + fmt.Fprintln(c.stdout, "Rotation completed") + return nil +} + +// Rollback an in progress key rotation. +func (c *recordingsEncryptionCommand) Rollback(ctx context.Context, tc *authclient.Client) error { + client := tc.RecordingEncryptionServiceClient() + if _, err := client.RollbackRotation(ctx, &recordingencryptionv1.RollbackRotationRequest{}); err != nil { + return trace.Errorf("rolling back encryption key rotation: %v", err) + } + + fmt.Fprintln(c.stdout, "Rotation rollback successful") + return nil +} + +// Status displays the current rotation status of the active encryption keys. +func (c *recordingsEncryptionCommand) Status(ctx context.Context, tc *authclient.Client) error { + client := tc.RecordingEncryptionServiceClient() + res, err := client.GetRotationState(ctx, &recordingencryptionv1.GetRotationStateRequest{}) + if err != nil { + return trace.Errorf("fetching encryption key status: %v", err) + } + + switch c.format { + case teleport.Text, "": + return trace.Wrap(c.writeStatusText(c.stdout, res.GetKeyPairStates())) + case teleport.YAML: + return trace.Wrap(c.writeStatusYAML(c.stdout, res.GetKeyPairStates())) + case teleport.JSON: + return trace.Wrap(c.writeStatusJSON(c.stdout, res.GetKeyPairStates())) + } + + return trace.Wrap(err, "writing encryption key status") +} + +func (c *recordingsEncryptionCommand) writeStatusJSON(w io.Writer, keyStates []*recordingencryptionv1.FingerprintWithState) error { + data, err := json.MarshalIndent(keyStates, "", " ") + if err != nil { + return trace.Wrap(err) + } + + _, err = w.Write(data) + return trace.Wrap(err) +} + +func (c *recordingsEncryptionCommand) writeStatusYAML(w io.Writer, keyStates []*recordingencryptionv1.FingerprintWithState) error { + return trace.Wrap(utils.WriteYAML(w, keyStates)) +} + +func (c *recordingsEncryptionCommand) writeStatusText(w io.Writer, keyStates []*recordingencryptionv1.FingerprintWithState) error { + rotationState := recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_UNSPECIFIED + t := asciitable.MakeTable([]string{"Key Pair Fingerprint", "State"}) + for _, pair := range keyStates { + if pair.State == recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_INACCESSIBLE { + rotationState = pair.State + } + + if pair.State == recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING { + if rotationState != recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_INACCESSIBLE { + rotationState = pair.State + } + } + + t.AddRow([]string{pair.Fingerprint, c.getFriendlyStatusString(pair.State)}) + } + + switch rotationState { + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_INACCESSIBLE: + fmt.Fprintln(w, "Rotation failed due to inaccessible key") + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING: + fmt.Fprintln(w, "Rotation in progress") + } + + _, err := t.AsBuffer().WriteTo(w) + return trace.Wrap(err) +} + +func (c *recordingsEncryptionCommand) getFriendlyStatusString(state recordingencryptionv1.KeyPairState) string { + switch state { + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING: + return "rotating" + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE: + return "active" + case recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_INACCESSIBLE: + return "inaccessible" + default: + return "unknown" + } +} diff --git a/tool/tctl/common/recordings_encryption_command_test.go b/tool/tctl/common/recordings_encryption_command_test.go new file mode 100644 index 0000000000000..2e7faa64a5abf --- /dev/null +++ b/tool/tctl/common/recordings_encryption_command_test.go @@ -0,0 +1,139 @@ +// Teleport +// Copyright (C) 2025 Gravitational, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package common + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1" + "github.com/gravitational/teleport/integration/helpers" + "github.com/gravitational/teleport/lib/auth/authclient" + "github.com/gravitational/teleport/lib/config" + "github.com/gravitational/teleport/tool/teleport/testenv" +) + +func TestRecordingEncryptionKeyRotation(t *testing.T) { + dynAddr := helpers.NewDynamicServiceAddr(t) + fileConfig := &config.FileConfig{ + Global: config.Global{ + DataDir: t.TempDir(), + }, + Auth: config.Auth{ + Service: config.Service{ + EnabledFlag: "true", + ListenAddress: dynAddr.AuthAddr, + }, + SessionRecordingConfig: &config.SessionRecordingConfig{ + Mode: "node", + Encryption: &config.SessionRecordingEncryptionConfig{ + Enabled: true, + }, + }, + }, + } + + process := makeAndRunTestAuthServer(t, withFileConfig(fileConfig), withFileDescriptors(dynAddr.Descriptors)) + clt, err := testenv.NewDefaultAuthClient(process) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, clt.Close()) + require.NoError(t, process.Close()) + require.NoError(t, process.Wait()) + }) + + // get initial status to confirm one active key exists + keyStates := getEncryptionKeyStates(t, clt) + require.Len(t, keyStates, 1) + initialKeyState := keyStates[0] + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, initialKeyState.State) + + // start key rotation + _, err = runRecordingsCommand(t, clt, []string{"recordings", "encryption", "rotate"}) + require.NoError(t, err) + + // refetch status to confirm original key is now 'rotating' and new key is 'active' + keyStates = getEncryptionKeyStates(t, clt) + require.Len(t, keyStates, 2) + rotatedKeyState := keyStates[0] + newKeyState := keyStates[1] + + require.Equal(t, initialKeyState.Fingerprint, rotatedKeyState.Fingerprint) + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING, rotatedKeyState.State) + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, newKeyState.State) + + // confirm a second rotation fails when one is already in progress + _, err = runRecordingsCommand(t, clt, []string{"recordings", "encryption", "rotate"}) + require.Error(t, err) + + // rollback rotation + _, err = runRecordingsCommand(t, clt, []string{"recordings", "encryption", "rollback-rotation"}) + require.NoError(t, err) + + // ensure initial key is the only active key remaining + keyStates = getEncryptionKeyStates(t, clt) + require.Len(t, keyStates, 1) + newKeyState = keyStates[0] + require.Equal(t, initialKeyState.Fingerprint, newKeyState.Fingerprint) + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, newKeyState.State) + + // start a new rotation + _, err = runRecordingsCommand(t, clt, []string{"recordings", "encryption", "rotate"}) + require.NoError(t, err) + + // confirm in progress rotation state + keyStates = getEncryptionKeyStates(t, clt) + require.Len(t, keyStates, 2) + rotatedKeyState = keyStates[0] + newKeyState = keyStates[1] + require.Equal(t, initialKeyState.Fingerprint, rotatedKeyState.Fingerprint) + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ROTATING, rotatedKeyState.State) + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, newKeyState.State) + + // complete rotation + _, err = runRecordingsCommand(t, clt, []string{"recordings", "encryption", "complete-rotation"}) + require.NoError(t, err) + + // ensure remaining active key is new + keyStates = getEncryptionKeyStates(t, clt) + require.Len(t, keyStates, 1) + finalKeyState := keyStates[0] + require.Equal(t, newKeyState.Fingerprint, finalKeyState.Fingerprint) + require.Equal(t, recordingencryptionv1.KeyPairState_KEY_PAIR_STATE_ACTIVE, finalKeyState.State) +} + +func getEncryptionKeyStates(t *testing.T, client *authclient.Client) []*recordingencryptionv1.FingerprintWithState { + var keyStates []*recordingencryptionv1.FingerprintWithState + out, err := runRecordingsCommand(t, client, []string{"recordings", "encryption", "status", "--format", "json"}) + require.NoError(t, err) + err = json.Unmarshal(out.Bytes(), &keyStates) + require.NoError(t, err) + + return keyStates +} + +func runRecordingsCommand(t *testing.T, client *authclient.Client, args []string) (*bytes.Buffer, error) { + var stdoutBuf bytes.Buffer + command := &RecordingsCommand{ + stdout: &stdoutBuf, + } + + return &stdoutBuf, runCommand(t, client, command, args) +} diff --git a/tool/tctl/common/tctl_test.go b/tool/tctl/common/tctl_test.go index d6da5c5f98b64..00c450f9338b9 100644 --- a/tool/tctl/common/tctl_test.go +++ b/tool/tctl/common/tctl_test.go @@ -33,6 +33,7 @@ import ( "github.com/gravitational/teleport/integration/helpers" "github.com/gravitational/teleport/lib/auth/authclient" "github.com/gravitational/teleport/lib/config" + "github.com/gravitational/teleport/lib/cryptosuites/cryptosuitestest" "github.com/gravitational/teleport/lib/modules" "github.com/gravitational/teleport/lib/service/servicecfg" "github.com/gravitational/teleport/lib/utils" @@ -48,7 +49,11 @@ func TestMain(m *testing.M) { } modules.SetInsecureTestMode(true) - os.Exit(m.Run()) + ctx, cancel := context.WithCancel(context.Background()) + cryptosuitestest.PrecomputeRSAKeys(ctx) + exitCode := m.Run() + cancel() + os.Exit(exitCode) } func BenchmarkInit(b *testing.B) {