Browse Source

add master side code for cluster wise exclusive lock

pull/1293/head
Chris Lu 5 years ago
parent
commit
77873b832b
  1. 33
      weed/pb/master.proto
  2. 545
      weed/pb/master_pb/master.pb.go
  3. 107
      weed/server/master_grpc_server_admin.go
  4. 3
      weed/server/master_server.go

33
weed/pb/master.proto

@ -27,6 +27,13 @@ service Seaweed {
} }
rpc ListMasterClients (ListMasterClientsRequest) returns (ListMasterClientsResponse) { rpc ListMasterClients (ListMasterClientsRequest) returns (ListMasterClientsResponse) {
} }
rpc LeaseAdminToken (LeaseAdminTokenRequest) returns (LeaseAdminTokenResponse) {
}
rpc ReleaseAdminToken (ReleaseAdminTokenRequest) returns (ReleaseAdminTokenResponse) {
}
rpc VerifyAdminToken (VerifyAdminTokenRequest) returns (VerifyAdminTokenResponse) {
}
} }
////////////////////////////////////////////////// //////////////////////////////////////////////////
@ -274,3 +281,29 @@ message ListMasterClientsRequest {
message ListMasterClientsResponse { message ListMasterClientsResponse {
repeated string grpc_addresses = 1; repeated string grpc_addresses = 1;
} }
message LeaseAdminTokenRequest {
int64 previous_token = 1;
int64 previous_lock_time = 2;
}
message LeaseAdminTokenResponse {
bool is_allowed = 1;
string error = 2;
int64 lock_ts_ns = 3;
int64 token = 4;
}
message ReleaseAdminTokenRequest {
int64 previous_token = 1;
int64 previous_lock_time = 2;
}
message ReleaseAdminTokenResponse {
}
message VerifyAdminTokenRequest {
int64 token = 1;
int64 lock_time = 2;
}
message VerifyAdminTokenResponse {
bool is_valid = 1;
}

545
weed/pb/master_pb/master.pb.go

@ -44,6 +44,12 @@ It has these top-level messages:
GetMasterConfigurationResponse GetMasterConfigurationResponse
ListMasterClientsRequest ListMasterClientsRequest
ListMasterClientsResponse ListMasterClientsResponse
LeaseAdminTokenRequest
LeaseAdminTokenResponse
ReleaseAdminTokenRequest
ReleaseAdminTokenResponse
VerifyAdminTokenRequest
VerifyAdminTokenResponse
*/ */
package master_pb package master_pb
@ -431,9 +437,7 @@ type VolumeEcShardInformationMessage struct {
func (m *VolumeEcShardInformationMessage) Reset() { *m = VolumeEcShardInformationMessage{} } func (m *VolumeEcShardInformationMessage) Reset() { *m = VolumeEcShardInformationMessage{} }
func (m *VolumeEcShardInformationMessage) String() string { return proto.CompactTextString(m) } func (m *VolumeEcShardInformationMessage) String() string { return proto.CompactTextString(m) }
func (*VolumeEcShardInformationMessage) ProtoMessage() {} func (*VolumeEcShardInformationMessage) ProtoMessage() {}
func (*VolumeEcShardInformationMessage) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{4}
}
func (*VolumeEcShardInformationMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *VolumeEcShardInformationMessage) GetId() uint32 { func (m *VolumeEcShardInformationMessage) GetId() uint32 {
if m != nil { if m != nil {
@ -1427,9 +1431,7 @@ type GetMasterConfigurationResponse struct {
func (m *GetMasterConfigurationResponse) Reset() { *m = GetMasterConfigurationResponse{} } func (m *GetMasterConfigurationResponse) Reset() { *m = GetMasterConfigurationResponse{} }
func (m *GetMasterConfigurationResponse) String() string { return proto.CompactTextString(m) } func (m *GetMasterConfigurationResponse) String() string { return proto.CompactTextString(m) }
func (*GetMasterConfigurationResponse) ProtoMessage() {} func (*GetMasterConfigurationResponse) ProtoMessage() {}
func (*GetMasterConfigurationResponse) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{32}
}
func (*GetMasterConfigurationResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} }
func (m *GetMasterConfigurationResponse) GetMetricsAddress() string { func (m *GetMasterConfigurationResponse) GetMetricsAddress() string {
if m != nil { if m != nil {
@ -1477,6 +1479,142 @@ func (m *ListMasterClientsResponse) GetGrpcAddresses() []string {
return nil return nil
} }
type LeaseAdminTokenRequest struct {
PreviousToken int64 `protobuf:"varint,1,opt,name=previous_token,json=previousToken" json:"previous_token,omitempty"`
PreviousLockTime int64 `protobuf:"varint,2,opt,name=previous_lock_time,json=previousLockTime" json:"previous_lock_time,omitempty"`
}
func (m *LeaseAdminTokenRequest) Reset() { *m = LeaseAdminTokenRequest{} }
func (m *LeaseAdminTokenRequest) String() string { return proto.CompactTextString(m) }
func (*LeaseAdminTokenRequest) ProtoMessage() {}
func (*LeaseAdminTokenRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} }
func (m *LeaseAdminTokenRequest) GetPreviousToken() int64 {
if m != nil {
return m.PreviousToken
}
return 0
}
func (m *LeaseAdminTokenRequest) GetPreviousLockTime() int64 {
if m != nil {
return m.PreviousLockTime
}
return 0
}
type LeaseAdminTokenResponse struct {
IsAllowed bool `protobuf:"varint,1,opt,name=is_allowed,json=isAllowed" json:"is_allowed,omitempty"`
Error string `protobuf:"bytes,2,opt,name=error" json:"error,omitempty"`
LockTsNs int64 `protobuf:"varint,3,opt,name=lock_ts_ns,json=lockTsNs" json:"lock_ts_ns,omitempty"`
Token int64 `protobuf:"varint,4,opt,name=token" json:"token,omitempty"`
}
func (m *LeaseAdminTokenResponse) Reset() { *m = LeaseAdminTokenResponse{} }
func (m *LeaseAdminTokenResponse) String() string { return proto.CompactTextString(m) }
func (*LeaseAdminTokenResponse) ProtoMessage() {}
func (*LeaseAdminTokenResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} }
func (m *LeaseAdminTokenResponse) GetIsAllowed() bool {
if m != nil {
return m.IsAllowed
}
return false
}
func (m *LeaseAdminTokenResponse) GetError() string {
if m != nil {
return m.Error
}
return ""
}
func (m *LeaseAdminTokenResponse) GetLockTsNs() int64 {
if m != nil {
return m.LockTsNs
}
return 0
}
func (m *LeaseAdminTokenResponse) GetToken() int64 {
if m != nil {
return m.Token
}
return 0
}
type ReleaseAdminTokenRequest struct {
PreviousToken int64 `protobuf:"varint,1,opt,name=previous_token,json=previousToken" json:"previous_token,omitempty"`
PreviousLockTime int64 `protobuf:"varint,2,opt,name=previous_lock_time,json=previousLockTime" json:"previous_lock_time,omitempty"`
}
func (m *ReleaseAdminTokenRequest) Reset() { *m = ReleaseAdminTokenRequest{} }
func (m *ReleaseAdminTokenRequest) String() string { return proto.CompactTextString(m) }
func (*ReleaseAdminTokenRequest) ProtoMessage() {}
func (*ReleaseAdminTokenRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} }
func (m *ReleaseAdminTokenRequest) GetPreviousToken() int64 {
if m != nil {
return m.PreviousToken
}
return 0
}
func (m *ReleaseAdminTokenRequest) GetPreviousLockTime() int64 {
if m != nil {
return m.PreviousLockTime
}
return 0
}
type ReleaseAdminTokenResponse struct {
}
func (m *ReleaseAdminTokenResponse) Reset() { *m = ReleaseAdminTokenResponse{} }
func (m *ReleaseAdminTokenResponse) String() string { return proto.CompactTextString(m) }
func (*ReleaseAdminTokenResponse) ProtoMessage() {}
func (*ReleaseAdminTokenResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} }
type VerifyAdminTokenRequest struct {
Token int64 `protobuf:"varint,1,opt,name=token" json:"token,omitempty"`
LockTime int64 `protobuf:"varint,2,opt,name=lock_time,json=lockTime" json:"lock_time,omitempty"`
}
func (m *VerifyAdminTokenRequest) Reset() { *m = VerifyAdminTokenRequest{} }
func (m *VerifyAdminTokenRequest) String() string { return proto.CompactTextString(m) }
func (*VerifyAdminTokenRequest) ProtoMessage() {}
func (*VerifyAdminTokenRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} }
func (m *VerifyAdminTokenRequest) GetToken() int64 {
if m != nil {
return m.Token
}
return 0
}
func (m *VerifyAdminTokenRequest) GetLockTime() int64 {
if m != nil {
return m.LockTime
}
return 0
}
type VerifyAdminTokenResponse struct {
IsValid bool `protobuf:"varint,1,opt,name=is_valid,json=isValid" json:"is_valid,omitempty"`
}
func (m *VerifyAdminTokenResponse) Reset() { *m = VerifyAdminTokenResponse{} }
func (m *VerifyAdminTokenResponse) String() string { return proto.CompactTextString(m) }
func (*VerifyAdminTokenResponse) ProtoMessage() {}
func (*VerifyAdminTokenResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} }
func (m *VerifyAdminTokenResponse) GetIsValid() bool {
if m != nil {
return m.IsValid
}
return false
}
func init() { func init() {
proto.RegisterType((*Heartbeat)(nil), "master_pb.Heartbeat") proto.RegisterType((*Heartbeat)(nil), "master_pb.Heartbeat")
proto.RegisterType((*HeartbeatResponse)(nil), "master_pb.HeartbeatResponse") proto.RegisterType((*HeartbeatResponse)(nil), "master_pb.HeartbeatResponse")
@ -1516,6 +1654,12 @@ func init() {
proto.RegisterType((*GetMasterConfigurationResponse)(nil), "master_pb.GetMasterConfigurationResponse") proto.RegisterType((*GetMasterConfigurationResponse)(nil), "master_pb.GetMasterConfigurationResponse")
proto.RegisterType((*ListMasterClientsRequest)(nil), "master_pb.ListMasterClientsRequest") proto.RegisterType((*ListMasterClientsRequest)(nil), "master_pb.ListMasterClientsRequest")
proto.RegisterType((*ListMasterClientsResponse)(nil), "master_pb.ListMasterClientsResponse") proto.RegisterType((*ListMasterClientsResponse)(nil), "master_pb.ListMasterClientsResponse")
proto.RegisterType((*LeaseAdminTokenRequest)(nil), "master_pb.LeaseAdminTokenRequest")
proto.RegisterType((*LeaseAdminTokenResponse)(nil), "master_pb.LeaseAdminTokenResponse")
proto.RegisterType((*ReleaseAdminTokenRequest)(nil), "master_pb.ReleaseAdminTokenRequest")
proto.RegisterType((*ReleaseAdminTokenResponse)(nil), "master_pb.ReleaseAdminTokenResponse")
proto.RegisterType((*VerifyAdminTokenRequest)(nil), "master_pb.VerifyAdminTokenRequest")
proto.RegisterType((*VerifyAdminTokenResponse)(nil), "master_pb.VerifyAdminTokenResponse")
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -1540,6 +1684,9 @@ type SeaweedClient interface {
LookupEcVolume(ctx context.Context, in *LookupEcVolumeRequest, opts ...grpc.CallOption) (*LookupEcVolumeResponse, error) LookupEcVolume(ctx context.Context, in *LookupEcVolumeRequest, opts ...grpc.CallOption) (*LookupEcVolumeResponse, error)
GetMasterConfiguration(ctx context.Context, in *GetMasterConfigurationRequest, opts ...grpc.CallOption) (*GetMasterConfigurationResponse, error) GetMasterConfiguration(ctx context.Context, in *GetMasterConfigurationRequest, opts ...grpc.CallOption) (*GetMasterConfigurationResponse, error)
ListMasterClients(ctx context.Context, in *ListMasterClientsRequest, opts ...grpc.CallOption) (*ListMasterClientsResponse, error) ListMasterClients(ctx context.Context, in *ListMasterClientsRequest, opts ...grpc.CallOption) (*ListMasterClientsResponse, error)
LeaseAdminToken(ctx context.Context, in *LeaseAdminTokenRequest, opts ...grpc.CallOption) (*LeaseAdminTokenResponse, error)
ReleaseAdminToken(ctx context.Context, in *ReleaseAdminTokenRequest, opts ...grpc.CallOption) (*ReleaseAdminTokenResponse, error)
VerifyAdminToken(ctx context.Context, in *VerifyAdminTokenRequest, opts ...grpc.CallOption) (*VerifyAdminTokenResponse, error)
} }
type seaweedClient struct { type seaweedClient struct {
@ -1693,6 +1840,33 @@ func (c *seaweedClient) ListMasterClients(ctx context.Context, in *ListMasterCli
return out, nil return out, nil
} }
func (c *seaweedClient) LeaseAdminToken(ctx context.Context, in *LeaseAdminTokenRequest, opts ...grpc.CallOption) (*LeaseAdminTokenResponse, error) {
out := new(LeaseAdminTokenResponse)
err := grpc.Invoke(ctx, "/master_pb.Seaweed/LeaseAdminToken", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedClient) ReleaseAdminToken(ctx context.Context, in *ReleaseAdminTokenRequest, opts ...grpc.CallOption) (*ReleaseAdminTokenResponse, error) {
out := new(ReleaseAdminTokenResponse)
err := grpc.Invoke(ctx, "/master_pb.Seaweed/ReleaseAdminToken", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *seaweedClient) VerifyAdminToken(ctx context.Context, in *VerifyAdminTokenRequest, opts ...grpc.CallOption) (*VerifyAdminTokenResponse, error) {
out := new(VerifyAdminTokenResponse)
err := grpc.Invoke(ctx, "/master_pb.Seaweed/VerifyAdminToken", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Seaweed service // Server API for Seaweed service
type SeaweedServer interface { type SeaweedServer interface {
@ -1707,6 +1881,9 @@ type SeaweedServer interface {
LookupEcVolume(context.Context, *LookupEcVolumeRequest) (*LookupEcVolumeResponse, error) LookupEcVolume(context.Context, *LookupEcVolumeRequest) (*LookupEcVolumeResponse, error)
GetMasterConfiguration(context.Context, *GetMasterConfigurationRequest) (*GetMasterConfigurationResponse, error) GetMasterConfiguration(context.Context, *GetMasterConfigurationRequest) (*GetMasterConfigurationResponse, error)
ListMasterClients(context.Context, *ListMasterClientsRequest) (*ListMasterClientsResponse, error) ListMasterClients(context.Context, *ListMasterClientsRequest) (*ListMasterClientsResponse, error)
LeaseAdminToken(context.Context, *LeaseAdminTokenRequest) (*LeaseAdminTokenResponse, error)
ReleaseAdminToken(context.Context, *ReleaseAdminTokenRequest) (*ReleaseAdminTokenResponse, error)
VerifyAdminToken(context.Context, *VerifyAdminTokenRequest) (*VerifyAdminTokenResponse, error)
} }
func RegisterSeaweedServer(s *grpc.Server, srv SeaweedServer) { func RegisterSeaweedServer(s *grpc.Server, srv SeaweedServer) {
@ -1927,6 +2104,60 @@ func _Seaweed_ListMasterClients_Handler(srv interface{}, ctx context.Context, de
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _Seaweed_LeaseAdminToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(LeaseAdminTokenRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedServer).LeaseAdminToken(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/master_pb.Seaweed/LeaseAdminToken",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedServer).LeaseAdminToken(ctx, req.(*LeaseAdminTokenRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Seaweed_ReleaseAdminToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ReleaseAdminTokenRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedServer).ReleaseAdminToken(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/master_pb.Seaweed/ReleaseAdminToken",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedServer).ReleaseAdminToken(ctx, req.(*ReleaseAdminTokenRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Seaweed_VerifyAdminToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(VerifyAdminTokenRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SeaweedServer).VerifyAdminToken(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/master_pb.Seaweed/VerifyAdminToken",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SeaweedServer).VerifyAdminToken(ctx, req.(*VerifyAdminTokenRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Seaweed_serviceDesc = grpc.ServiceDesc{ var _Seaweed_serviceDesc = grpc.ServiceDesc{
ServiceName: "master_pb.Seaweed", ServiceName: "master_pb.Seaweed",
HandlerType: (*SeaweedServer)(nil), HandlerType: (*SeaweedServer)(nil),
@ -1967,6 +2198,18 @@ var _Seaweed_serviceDesc = grpc.ServiceDesc{
MethodName: "ListMasterClients", MethodName: "ListMasterClients",
Handler: _Seaweed_ListMasterClients_Handler, Handler: _Seaweed_ListMasterClients_Handler,
}, },
{
MethodName: "LeaseAdminToken",
Handler: _Seaweed_LeaseAdminToken_Handler,
},
{
MethodName: "ReleaseAdminToken",
Handler: _Seaweed_ReleaseAdminToken_Handler,
},
{
MethodName: "VerifyAdminToken",
Handler: _Seaweed_VerifyAdminToken_Handler,
},
}, },
Streams: []grpc.StreamDesc{ Streams: []grpc.StreamDesc{
{ {
@ -1988,142 +2231,156 @@ var _Seaweed_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("master.proto", fileDescriptor0) } func init() { proto.RegisterFile("master.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 2183 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xd4, 0x59, 0xcd, 0x6f, 0x1b, 0xc7,
0x15, 0xf7, 0x92, 0x94, 0x48, 0x3e, 0x7e, 0x8f, 0x64, 0x85, 0x66, 0x62, 0x8b, 0xde, 0xa4, 0x88,
0xec, 0xa6, 0x6a, 0xaa, 0x04, 0x68, 0xd0, 0x34, 0x08, 0x2c, 0x59, 0x71, 0x05, 0x5b, 0x8a, 0xbd,
0x72, 0x1d, 0xa0, 0x40, 0xb1, 0x19, 0xee, 0x8e, 0xa4, 0x85, 0xf6, 0xab, 0xbb, 0x43, 0x59, 0x4c,
0x2f, 0x05, 0x7a, 0xec, 0xa9, 0xe8, 0xa1, 0xff, 0x42, 0x2f, 0x3d, 0xb5, 0x97, 0x5e, 0x72, 0xe9,
0x7f, 0xd4, 0x6b, 0x2e, 0xc5, 0x7c, 0xed, 0xce, 0x2e, 0x49, 0x29, 0x0a, 0x90, 0x83, 0x6f, 0xbb,
0xef, 0xbd, 0x79, 0xf3, 0xf6, 0xf7, 0xe6, 0xbd, 0xf9, 0x3d, 0x12, 0xda, 0x01, 0x4e, 0x29, 0x49,
0xb6, 0xe3, 0x24, 0xa2, 0x11, 0x6a, 0x8a, 0x37, 0x3b, 0x9e, 0x98, 0x7f, 0x59, 0x85, 0xe6, 0x6f,
0x08, 0x4e, 0xe8, 0x84, 0x60, 0x8a, 0xba, 0x50, 0xf1, 0xe2, 0xa1, 0x31, 0x36, 0xb6, 0x9a, 0x56,
0xc5, 0x8b, 0x11, 0x82, 0x5a, 0x1c, 0x25, 0x74, 0x58, 0x19, 0x1b, 0x5b, 0x1d, 0x8b, 0x3f, 0xa3,
0xbb, 0x00, 0xf1, 0x74, 0xe2, 0x7b, 0x8e, 0x3d, 0x4d, 0xfc, 0x61, 0x95, 0xdb, 0x36, 0x85, 0xe4,
0xb7, 0x89, 0x8f, 0xb6, 0xa0, 0x1f, 0xe0, 0x4b, 0xfb, 0x22, 0xf2, 0xa7, 0x01, 0xb1, 0x9d, 0x68,
0x1a, 0xd2, 0x61, 0x8d, 0x2f, 0xef, 0x06, 0xf8, 0xf2, 0x15, 0x17, 0xef, 0x31, 0x29, 0x1a, 0xb3,
0xa8, 0x2e, 0xed, 0x13, 0xcf, 0x27, 0xf6, 0x39, 0x99, 0x0d, 0x57, 0xc6, 0xc6, 0x56, 0xcd, 0x82,
0x00, 0x5f, 0x7e, 0xe1, 0xf9, 0xe4, 0x29, 0x99, 0xa1, 0x4d, 0x68, 0xb9, 0x98, 0x62, 0xdb, 0x21,
0x21, 0x25, 0xc9, 0x70, 0x95, 0xef, 0x05, 0x4c, 0xb4, 0xc7, 0x25, 0x2c, 0xbe, 0x04, 0x3b, 0xe7,
0xc3, 0x3a, 0xd7, 0xf0, 0x67, 0x16, 0x1f, 0x76, 0x03, 0x2f, 0xb4, 0x79, 0xe4, 0x0d, 0xbe, 0x75,
0x93, 0x4b, 0x9e, 0xb3, 0xf0, 0x3f, 0x83, 0xba, 0x88, 0x2d, 0x1d, 0x36, 0xc7, 0xd5, 0xad, 0xd6,
0xce, 0xbb, 0xdb, 0x19, 0x1a, 0xdb, 0x22, 0xbc, 0x83, 0xf0, 0x24, 0x4a, 0x02, 0x4c, 0xbd, 0x28,
0x3c, 0x24, 0x69, 0x8a, 0x4f, 0x89, 0xa5, 0xd6, 0xa0, 0x03, 0x68, 0x85, 0xe4, 0xb5, 0xad, 0x5c,
0x00, 0x77, 0xb1, 0x35, 0xe7, 0xe2, 0xf8, 0x2c, 0x4a, 0xe8, 0x02, 0x3f, 0x10, 0x92, 0xd7, 0xaf,
0xa4, 0xab, 0x17, 0xd0, 0x73, 0x89, 0x4f, 0x28, 0x71, 0x33, 0x77, 0xad, 0x1b, 0xba, 0xeb, 0x4a,
0x07, 0xca, 0xe5, 0x7b, 0xd0, 0x3d, 0xc3, 0xa9, 0x1d, 0x46, 0x99, 0xc7, 0xf6, 0xd8, 0xd8, 0x6a,
0x58, 0xed, 0x33, 0x9c, 0x1e, 0x45, 0xca, 0xea, 0x09, 0x34, 0x89, 0x63, 0xa7, 0x67, 0x38, 0x71,
0xd3, 0x61, 0x9f, 0x6f, 0xf9, 0x70, 0x6e, 0xcb, 0x7d, 0xe7, 0x98, 0x19, 0x2c, 0xd8, 0xb4, 0x41,
0x84, 0x2a, 0x45, 0x47, 0xd0, 0x61, 0x60, 0xe4, 0xce, 0x06, 0x37, 0x76, 0xc6, 0xd0, 0xdc, 0x57,
0xfe, 0x5e, 0xc1, 0x40, 0x21, 0x92, 0xfb, 0x44, 0x37, 0xf6, 0xa9, 0x60, 0xcd, 0xfc, 0xbe, 0x0f,
0x7d, 0x09, 0x4b, 0xee, 0x76, 0x8d, 0x03, 0xd3, 0xe1, 0xc0, 0x28, 0x43, 0xf3, 0x4f, 0x15, 0x18,
0x64, 0xd5, 0x60, 0x91, 0x34, 0x8e, 0xc2, 0x94, 0xa0, 0x87, 0x30, 0x90, 0xc7, 0x39, 0xf5, 0xbe,
0x21, 0xb6, 0xef, 0x05, 0x1e, 0xe5, 0x45, 0x52, 0xb3, 0x7a, 0x42, 0x71, 0xec, 0x7d, 0x43, 0x9e,
0x31, 0x31, 0xda, 0x80, 0x55, 0x9f, 0x60, 0x97, 0x24, 0xbc, 0x66, 0x9a, 0x96, 0x7c, 0x43, 0xef,
0x43, 0x2f, 0x20, 0x34, 0xf1, 0x9c, 0xd4, 0xc6, 0xae, 0x9b, 0x90, 0x34, 0x95, 0xa5, 0xd3, 0x95,
0xe2, 0x47, 0x42, 0x8a, 0x3e, 0x81, 0xa1, 0x32, 0xf4, 0xd8, 0x19, 0xbf, 0xc0, 0xbe, 0x9d, 0x12,
0x27, 0x0a, 0xdd, 0x54, 0xd6, 0xd1, 0x86, 0xd4, 0x1f, 0x48, 0xf5, 0xb1, 0xd0, 0xa2, 0xc7, 0xd0,
0x4f, 0x69, 0x94, 0xe0, 0x53, 0x62, 0x4f, 0xb0, 0x73, 0x4e, 0xd8, 0x8a, 0x15, 0x0e, 0xde, 0x1d,
0x0d, 0xbc, 0x63, 0x61, 0xb2, 0x2b, 0x2c, 0xac, 0x5e, 0x5a, 0x78, 0x4f, 0xcd, 0xef, 0xaa, 0x30,
0x5c, 0x56, 0x06, 0xbc, 0x3f, 0xb8, 0xfc, 0xd3, 0x3b, 0x56, 0xc5, 0x73, 0x59, 0xfd, 0x31, 0x48,
0xf8, 0xb7, 0xd6, 0x2c, 0xfe, 0x8c, 0xee, 0x01, 0x38, 0x91, 0xef, 0x13, 0x87, 0x2d, 0x94, 0x1f,
0xa9, 0x49, 0x58, 0x7d, 0xf2, 0x92, 0xcf, 0x5b, 0x43, 0xcd, 0x6a, 0x32, 0x89, 0xe8, 0x0a, 0xf7,
0xa1, 0x2d, 0xd2, 0x27, 0x0d, 0x44, 0x57, 0x68, 0x09, 0x99, 0x30, 0xf9, 0x00, 0x90, 0x3a, 0x26,
0x93, 0x59, 0x66, 0xb8, 0xca, 0x0d, 0xfb, 0x52, 0xb3, 0x3b, 0x53, 0xd6, 0x6f, 0x43, 0x33, 0x21,
0xd8, 0xb5, 0xa3, 0xd0, 0x9f, 0xf1, 0x46, 0xd1, 0xb0, 0x1a, 0x4c, 0xf0, 0x65, 0xe8, 0xcf, 0xd0,
0x4f, 0x61, 0x90, 0x90, 0xd8, 0xf7, 0x1c, 0x6c, 0xc7, 0x3e, 0x76, 0x48, 0x40, 0x42, 0xd5, 0x33,
0xfa, 0x52, 0xf1, 0x5c, 0xc9, 0xd1, 0x10, 0xea, 0x17, 0x24, 0x49, 0xd9, 0x67, 0x35, 0xb9, 0x89,
0x7a, 0x45, 0x7d, 0xa8, 0x52, 0xea, 0x0f, 0x81, 0x4b, 0xd9, 0x23, 0x7a, 0x00, 0x7d, 0x27, 0x0a,
0x62, 0xec, 0x50, 0x3b, 0x21, 0x17, 0x1e, 0x5f, 0xd4, 0xe2, 0xea, 0x9e, 0x94, 0x5b, 0x52, 0xcc,
0x3e, 0x27, 0x88, 0x5c, 0xef, 0xc4, 0x23, 0xae, 0x8d, 0xa9, 0x4c, 0x36, 0x2f, 0xdc, 0xaa, 0xd5,
0x57, 0x9a, 0x47, 0x54, 0xa4, 0x19, 0x6d, 0xc3, 0x5a, 0x42, 0x82, 0x88, 0x12, 0x5b, 0x25, 0x3b,
0xc4, 0x01, 0x19, 0x76, 0x38, 0xce, 0x03, 0xa1, 0x92, 0x39, 0x3e, 0xc2, 0x01, 0x61, 0xde, 0x4b,
0xf6, 0xac, 0xd7, 0x76, 0xb9, 0x79, 0xbf, 0x60, 0xfe, 0x94, 0xcc, 0xcc, 0x7f, 0x18, 0x70, 0xf7,
0xca, 0x96, 0x33, 0x77, 0x04, 0xae, 0x4b, 0xf7, 0x8f, 0x85, 0xb0, 0x39, 0x85, 0xcd, 0x6b, 0x1a,
0xc1, 0x35, 0xb1, 0x56, 0xe6, 0x62, 0x35, 0xa1, 0x43, 0x1c, 0xdb, 0x0b, 0x5d, 0x72, 0x69, 0x4f,
0x3c, 0x2a, 0x4a, 0xb4, 0x63, 0xb5, 0x88, 0x73, 0xc0, 0x64, 0xbb, 0x1e, 0x4d, 0xcd, 0x6f, 0x0d,
0xe8, 0x16, 0x6b, 0x88, 0x55, 0x01, 0x9d, 0xc5, 0x44, 0xde, 0x9b, 0xfc, 0x59, 0x6e, 0x5d, 0x91,
0x37, 0xa9, 0x8b, 0x0e, 0x00, 0xe2, 0x24, 0x8a, 0x49, 0x42, 0x3d, 0xc2, 0xfc, 0xb2, 0xb2, 0x7c,
0xb0, 0xb4, 0x2c, 0xb7, 0x9f, 0x67, 0xb6, 0xfb, 0x21, 0x4d, 0x66, 0x96, 0xb6, 0x78, 0xf4, 0x19,
0xf4, 0x4a, 0x6a, 0x86, 0x0e, 0xcb, 0xaa, 0x08, 0x80, 0x3d, 0xa2, 0x75, 0x58, 0xb9, 0xc0, 0xfe,
0x94, 0xc8, 0x10, 0xc4, 0xcb, 0xaf, 0x2a, 0x9f, 0x18, 0x66, 0x1d, 0x56, 0xf6, 0x83, 0x98, 0xce,
0xd8, 0x97, 0xf4, 0x8e, 0xa7, 0x31, 0x49, 0x76, 0xfd, 0xc8, 0x39, 0xdf, 0xbf, 0xa4, 0x09, 0x46,
0x5f, 0x42, 0x97, 0x24, 0x38, 0x9d, 0x26, 0xac, 0xaa, 0x5c, 0x2f, 0x3c, 0xe5, 0x3e, 0x8b, 0x57,
0x52, 0x69, 0xcd, 0xf6, 0xbe, 0x58, 0xb0, 0xc7, 0xed, 0xad, 0x0e, 0xd1, 0x5f, 0x47, 0xbf, 0x83,
0x4e, 0x41, 0xcf, 0xc0, 0x62, 0x17, 0xb8, 0xcc, 0x0a, 0x7f, 0x66, 0x4d, 0x33, 0xc6, 0x89, 0x47,
0x67, 0x92, 0x68, 0xc8, 0x37, 0xd6, 0x2a, 0x64, 0xe3, 0xf5, 0x5c, 0x01, 0x5a, 0xc7, 0x6a, 0x0a,
0xc9, 0x81, 0x9b, 0x9a, 0x4f, 0x60, 0xfd, 0x29, 0x21, 0xf1, 0x5e, 0x14, 0x86, 0xc4, 0xa1, 0xc4,
0xb5, 0xc8, 0x1f, 0xa6, 0x24, 0xa5, 0x6c, 0x0b, 0x5e, 0x13, 0x32, 0x1f, 0xec, 0x99, 0x75, 0x81,
0xd3, 0x24, 0x76, 0x6c, 0x8d, 0xce, 0x34, 0x98, 0x80, 0x71, 0x02, 0xf3, 0xef, 0x06, 0x74, 0xc5,
0x59, 0x7a, 0x16, 0x39, 0xfc, 0x04, 0x31, 0x44, 0x19, 0xbd, 0x91, 0x88, 0x4e, 0x13, 0xbf, 0xc4,
0x7b, 0x2a, 0x65, 0xde, 0x73, 0x07, 0x1a, 0x9c, 0x18, 0xe4, 0x91, 0xd6, 0xd9, 0x5d, 0xef, 0xb9,
0x69, 0xde, 0xd2, 0x5c, 0xa1, 0xae, 0x71, 0x75, 0x4b, 0xdd, 0xdd, 0xcc, 0x24, 0xbf, 0x36, 0x56,
0xf4, 0x6b, 0xc3, 0x7c, 0x09, 0x6b, 0xcf, 0xa2, 0xe8, 0x7c, 0x1a, 0x8b, 0xf0, 0xd4, 0x17, 0x16,
0x81, 0x31, 0xc6, 0x55, 0x16, 0x4b, 0x06, 0xcc, 0x75, 0xe7, 0xdc, 0xfc, 0x9f, 0x01, 0xeb, 0x45,
0xb7, 0xf2, 0xa6, 0xfb, 0x1a, 0xd6, 0x32, 0xbf, 0xb6, 0x2f, 0xb1, 0x10, 0x1b, 0xb4, 0x76, 0x3e,
0xd4, 0xce, 0xc0, 0xa2, 0xd5, 0x8a, 0x3d, 0xb9, 0x0a, 0x44, 0x6b, 0x70, 0x51, 0x92, 0xa4, 0xa3,
0x4b, 0xe8, 0x97, 0xcd, 0x58, 0x6e, 0xb2, 0x5d, 0x25, 0xe2, 0x0d, 0xb5, 0x12, 0xfd, 0x02, 0x9a,
0x79, 0x20, 0x15, 0x1e, 0xc8, 0x5a, 0x21, 0x10, 0xb9, 0x57, 0x6e, 0xc5, 0xce, 0x3e, 0x49, 0x92,
0x28, 0x91, 0xdd, 0x48, 0xbc, 0x98, 0x9f, 0x42, 0xe3, 0x07, 0x67, 0xd7, 0xfc, 0x57, 0x05, 0x3a,
0x8f, 0xd2, 0xd4, 0x3b, 0x0d, 0x55, 0x0a, 0xd6, 0x61, 0x45, 0xdc, 0x3b, 0x82, 0x08, 0x88, 0x17,
0x34, 0x86, 0x96, 0x6c, 0x6a, 0x1a, 0xf4, 0xba, 0xe8, 0xda, 0x7e, 0x29, 0x1b, 0x5d, 0x4d, 0x84,
0xc6, 0xae, 0x92, 0x12, 0x0b, 0x5e, 0x59, 0xca, 0x82, 0x57, 0x35, 0x16, 0xfc, 0x36, 0x34, 0xf9,
0xa2, 0x30, 0x72, 0x89, 0xa4, 0xc7, 0x0d, 0x26, 0x38, 0x8a, 0x5c, 0x82, 0x76, 0x60, 0x23, 0x20,
0x41, 0x94, 0xcc, 0xec, 0x00, 0xc7, 0x36, 0x23, 0xe1, 0x9c, 0xd8, 0x04, 0x13, 0xd9, 0x98, 0x91,
0xd0, 0x1e, 0xe2, 0xf8, 0x10, 0x5f, 0x32, 0x6e, 0x73, 0x38, 0x41, 0x3b, 0x70, 0xfb, 0xab, 0xc4,
0xa3, 0x78, 0xe2, 0x93, 0x22, 0xb9, 0x17, 0x8d, 0x7a, 0x4d, 0x29, 0x35, 0x86, 0x6f, 0xfe, 0xcd,
0x80, 0xae, 0x42, 0x4d, 0x9e, 0xb0, 0x3e, 0x54, 0x4f, 0xb2, 0x2c, 0xb3, 0x47, 0x95, 0x8b, 0xca,
0xb2, 0x5c, 0xcc, 0x4d, 0x18, 0x19, 0xf2, 0x35, 0x1d, 0xf9, 0x2c, 0xe9, 0x2b, 0x5a, 0xd2, 0x19,
0x34, 0x78, 0x4a, 0xcf, 0x14, 0x34, 0xec, 0xd9, 0x3c, 0x85, 0xc1, 0x31, 0xc5, 0xd4, 0x4b, 0xa9,
0xe7, 0xa4, 0x2a, 0x9d, 0xa5, 0xc4, 0x19, 0xd7, 0x25, 0xae, 0xb2, 0x2c, 0x71, 0xd5, 0x2c, 0x71,
0xe6, 0x7f, 0x0d, 0x40, 0xfa, 0x4e, 0x12, 0x82, 0x1f, 0x61, 0x2b, 0x06, 0x19, 0x8d, 0x28, 0xa3,
0x8a, 0x8c, 0x8e, 0x49, 0x52, 0xc5, 0x25, 0x2c, 0x7d, 0xec, 0x34, 0x4c, 0x53, 0xe2, 0x0a, 0xad,
0x60, 0x54, 0x0d, 0x26, 0xe0, 0xca, 0x22, 0x21, 0x5b, 0x2d, 0x11, 0x32, 0xf3, 0x11, 0xb4, 0xe4,
0xe5, 0xf4, 0x92, 0x5d, 0x6c, 0xd7, 0x47, 0x2f, 0xa3, 0xab, 0xe4, 0x40, 0x8c, 0x01, 0xf6, 0xf2,
0xe8, 0x17, 0xb4, 0x67, 0xf3, 0x8f, 0x70, 0x3b, 0xb7, 0x78, 0xe6, 0xa5, 0x54, 0xe5, 0xe5, 0x63,
0xd8, 0xf0, 0x42, 0xc7, 0x9f, 0xba, 0xc4, 0x0e, 0xd9, 0xf5, 0xee, 0x67, 0x93, 0x8d, 0xc1, 0xa9,
0xdc, 0xba, 0xd4, 0x1e, 0x71, 0xa5, 0x9a, 0x70, 0x3e, 0x00, 0xa4, 0x56, 0x11, 0x27, 0x5b, 0x51,
0xe1, 0x2b, 0xfa, 0x52, 0xb3, 0xef, 0x48, 0x6b, 0xf3, 0x05, 0x6c, 0x94, 0x37, 0x97, 0xa9, 0xfa,
0x25, 0xb4, 0x72, 0xd8, 0x55, 0x1f, 0xbc, 0xad, 0xb5, 0x9f, 0x7c, 0x9d, 0xa5, 0x5b, 0x9a, 0x3f,
0x83, 0xb7, 0x72, 0xd5, 0x63, 0xde, 0xe8, 0xaf, 0xb8, 0x9d, 0xcc, 0x11, 0x0c, 0xe7, 0xcd, 0x45,
0x0c, 0xe6, 0x5f, 0xab, 0xd0, 0x7e, 0x2c, 0x2b, 0x97, 0x71, 0x1c, 0x8d, 0xd5, 0x08, 0x6a, 0x71,
0x1f, 0xda, 0x85, 0x82, 0x14, 0x64, 0xbc, 0x75, 0xa1, 0x8d, 0xda, 0x8b, 0x86, 0xf2, 0x2a, 0x37,
0x2b, 0x0f, 0xe5, 0x0f, 0x61, 0x70, 0x92, 0x10, 0x32, 0x3f, 0xbf, 0xd7, 0xac, 0x1e, 0x53, 0xe8,
0xb6, 0xdb, 0xb0, 0x86, 0x1d, 0xea, 0x5d, 0x94, 0xac, 0xc5, 0xf9, 0x1a, 0x08, 0x95, 0x6e, 0xff,
0x45, 0x16, 0xa8, 0x17, 0x9e, 0x44, 0xe9, 0x70, 0xf5, 0xfb, 0xcf, 0xdf, 0xf2, 0x6b, 0x98, 0x26,
0x45, 0xcf, 0xa1, 0xab, 0xe6, 0x38, 0xe9, 0xa9, 0x7e, 0xe3, 0x19, 0xb1, 0x4d, 0x72, 0x55, 0xaa,
0x91, 0xea, 0xc2, 0x97, 0x34, 0xc4, 0x97, 0x08, 0x95, 0xde, 0xd8, 0xfe, 0x5d, 0x81, 0x86, 0x85,
0x9d, 0xf3, 0x37, 0x3b, 0x1f, 0x9f, 0x43, 0x2f, 0xbb, 0x23, 0x0a, 0x29, 0x79, 0x4b, 0x03, 0x52,
0x3f, 0x7a, 0x56, 0xc7, 0xd5, 0xde, 0x96, 0xc2, 0x56, 0x5f, 0x06, 0xdb, 0x3f, 0x2b, 0xd0, 0x7d,
0x9c, 0xdd, 0x5b, 0x6f, 0x36, 0x78, 0x3b, 0x00, 0xec, 0xa2, 0x2d, 0xe0, 0xa6, 0x13, 0x13, 0x75,
0x3c, 0xac, 0x66, 0x22, 0x9f, 0x6e, 0x8e, 0xd7, 0xb7, 0x15, 0x68, 0xbf, 0x8c, 0xe2, 0xc8, 0x8f,
0x4e, 0x67, 0x6f, 0x36, 0x5a, 0xfb, 0x30, 0xd0, 0x38, 0x4c, 0x01, 0xb4, 0x3b, 0xa5, 0xc3, 0x96,
0x1f, 0x0e, 0xab, 0xe7, 0x16, 0xde, 0x6f, 0x0e, 0xe0, 0x1a, 0x0c, 0x24, 0xaf, 0xcf, 0xaf, 0x14,
0xf3, 0xcf, 0x06, 0x20, 0x5d, 0x2a, 0x7b, 0xfd, 0xaf, 0xa1, 0x43, 0x25, 0xd6, 0x3c, 0x3e, 0x39,
0xf9, 0xe8, 0xb5, 0xa0, 0xe7, 0xc2, 0x6a, 0x53, 0x3d, 0x33, 0x3f, 0x87, 0xf5, 0xb9, 0xdf, 0x88,
0x18, 0xa1, 0x12, 0x19, 0x19, 0x94, 0x7e, 0x26, 0x3a, 0x9c, 0x98, 0x1f, 0xc3, 0x6d, 0x41, 0xa2,
0xd5, 0x3d, 0xa4, 0xee, 0x87, 0x39, 0x36, 0xdc, 0xc9, 0xd9, 0xb0, 0xf9, 0x9d, 0x01, 0x1b, 0xe5,
0x65, 0x32, 0xfe, 0xab, 0xd6, 0x21, 0x0c, 0x48, 0xf6, 0x4b, 0x9d, 0xd7, 0x0b, 0x3a, 0xfd, 0xd1,
0x1c, 0xaf, 0x2f, 0xfb, 0xde, 0x56, 0x7d, 0x34, 0xa7, 0xf6, 0xfd, 0xb4, 0x28, 0x48, 0x47, 0x18,
0x06, 0x73, 0x66, 0x6c, 0x2a, 0x52, 0xfb, 0xca, 0x98, 0xea, 0x72, 0xe1, 0x0f, 0x20, 0xf6, 0xe6,
0x26, 0xdc, 0x7d, 0x42, 0xe8, 0x21, 0xb7, 0xd9, 0x8b, 0xc2, 0x13, 0xef, 0x74, 0x9a, 0x08, 0xa3,
0x3c, 0xb5, 0xf7, 0x96, 0x59, 0x48, 0x98, 0x16, 0xfc, 0x10, 0x67, 0xdc, 0xf8, 0x87, 0xb8, 0xca,
0x55, 0x3f, 0xc4, 0x99, 0x9f, 0xc2, 0x90, 0x9d, 0x2c, 0x19, 0x85, 0xef, 0x91, 0x90, 0x66, 0x3c,
0x73, 0x13, 0x5a, 0x0e, 0x97, 0xd8, 0xda, 0x4f, 0x06, 0x20, 0x44, 0x8c, 0x5f, 0x99, 0xbb, 0x70,
0x67, 0xc1, 0x62, 0x19, 0xfc, 0x4f, 0xa0, 0xcb, 0xa7, 0x58, 0x19, 0x39, 0x51, 0xb3, 0x5f, 0x87,
0x49, 0x1f, 0x29, 0xe1, 0xce, 0x7f, 0xea, 0x50, 0x3f, 0x26, 0xf8, 0x35, 0x21, 0x2e, 0x3a, 0x80,
0xce, 0x31, 0x09, 0xdd, 0xfc, 0x37, 0xfe, 0x75, 0x0d, 0xe4, 0x4c, 0x3a, 0x7a, 0x67, 0x91, 0x34,
0xe3, 0x20, 0xb7, 0xb6, 0x8c, 0x0f, 0x0d, 0xf4, 0x02, 0x3a, 0x85, 0x79, 0x1b, 0x6d, 0x6a, 0x8b,
0x16, 0x4d, 0xe2, 0xa3, 0x3b, 0x73, 0x37, 0xb2, 0x4a, 0x6b, 0xe6, 0xb2, 0xad, 0x8f, 0x92, 0xe8,
0xde, 0xd2, 0x19, 0x53, 0x38, 0xdc, 0xbc, 0x66, 0x06, 0x35, 0x6f, 0xa1, 0xcf, 0x61, 0x55, 0xcc,
0x1c, 0x68, 0xa8, 0x19, 0x17, 0x86, 0xb7, 0x42, 0x5c, 0xc5, 0x01, 0xc5, 0xbc, 0x85, 0x9e, 0x02,
0xe4, 0xac, 0x1d, 0xbd, 0x53, 0xf8, 0x91, 0xa6, 0x34, 0x36, 0x8c, 0xee, 0x2e, 0xd1, 0x66, 0xce,
0xbe, 0x82, 0x6e, 0x91, 0x5b, 0xa2, 0xf1, 0x42, 0xfa, 0xa8, 0x35, 0xa8, 0xd1, 0xfd, 0x2b, 0x2c,
0x32, 0xc7, 0xbf, 0x87, 0x7e, 0x99, 0x32, 0x22, 0x73, 0xe1, 0xc2, 0x02, 0xfd, 0x1c, 0xbd, 0x7b,
0xa5, 0x8d, 0x0e, 0x42, 0xde, 0x23, 0x0b, 0x20, 0xcc, 0x35, 0xd4, 0x02, 0x08, 0xf3, 0x8d, 0x55,
0x80, 0x50, 0x6c, 0x2c, 0x05, 0x10, 0x16, 0xb6, 0xc1, 0x02, 0x08, 0x8b, 0xbb, 0x92, 0x79, 0x0b,
0x45, 0xb0, 0xb1, 0xb8, 0xdc, 0x91, 0xfe, 0x83, 0xd5, 0x95, 0x3d, 0x63, 0xf4, 0xe0, 0x7b, 0x58,
0x66, 0x1b, 0x7e, 0x0d, 0x83, 0xb9, 0xea, 0x44, 0x3a, 0xa4, 0xcb, 0x0a, 0x7f, 0xf4, 0xde, 0xd5,
0x46, 0x6a, 0x87, 0xc9, 0x2a, 0xff, 0x8b, 0xee, 0xa3, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0x6a,
0xee, 0xfc, 0x90, 0xb2, 0x1b, 0x00, 0x00,
// 2409 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xd4, 0x59, 0x4b, 0x6f, 0x1c, 0xc7,
0xf1, 0xd7, 0xec, 0xf2, 0xb1, 0x5b, 0xcb, 0x5d, 0xee, 0x36, 0x29, 0x6a, 0xb9, 0x96, 0x44, 0x6a,
0x6c, 0xc3, 0x94, 0xfe, 0xfe, 0x33, 0x0e, 0xed, 0x20, 0x46, 0x1c, 0xc3, 0xa0, 0x28, 0x5a, 0x21,
0x44, 0xd2, 0xd2, 0x90, 0x91, 0x01, 0x03, 0xc1, 0xb8, 0x39, 0xd3, 0xa4, 0x1a, 0x9c, 0x57, 0xa6,
0x7b, 0x29, 0xae, 0x73, 0x09, 0x92, 0x63, 0x4e, 0x41, 0x0e, 0xf9, 0x0a, 0xb9, 0xe4, 0x94, 0x9c,
0x7d, 0xc9, 0x77, 0xc8, 0x07, 0xc9, 0xd5, 0x97, 0xa0, 0x1f, 0x33, 0xd3, 0x33, 0xbb, 0x4b, 0x9a,
0x06, 0x1c, 0x40, 0xb7, 0xe9, 0xaa, 0xea, 0xea, 0xea, 0x5f, 0x75, 0xd7, 0xa3, 0x07, 0x16, 0x42,
0xcc, 0x38, 0x49, 0x37, 0x93, 0x34, 0xe6, 0x31, 0x6a, 0xaa, 0x91, 0x9b, 0x9c, 0xd8, 0x7f, 0x9a,
0x83, 0xe6, 0xaf, 0x08, 0x4e, 0xf9, 0x09, 0xc1, 0x1c, 0x75, 0xa0, 0x46, 0x93, 0xbe, 0xb5, 0x6e,
0x6d, 0x34, 0x9d, 0x1a, 0x4d, 0x10, 0x82, 0x99, 0x24, 0x4e, 0x79, 0xbf, 0xb6, 0x6e, 0x6d, 0xb4,
0x1d, 0xf9, 0x8d, 0xee, 0x01, 0x24, 0xc3, 0x93, 0x80, 0x7a, 0xee, 0x30, 0x0d, 0xfa, 0x75, 0x29,
0xdb, 0x54, 0x94, 0x5f, 0xa7, 0x01, 0xda, 0x80, 0x6e, 0x88, 0x2f, 0xdd, 0x8b, 0x38, 0x18, 0x86,
0xc4, 0xf5, 0xe2, 0x61, 0xc4, 0xfb, 0x33, 0x72, 0x7a, 0x27, 0xc4, 0x97, 0x2f, 0x25, 0x79, 0x47,
0x50, 0xd1, 0xba, 0xb0, 0xea, 0xd2, 0x3d, 0xa5, 0x01, 0x71, 0xcf, 0xc9, 0xa8, 0x3f, 0xbb, 0x6e,
0x6d, 0xcc, 0x38, 0x10, 0xe2, 0xcb, 0xcf, 0x69, 0x40, 0x9e, 0x91, 0x11, 0x5a, 0x83, 0x96, 0x8f,
0x39, 0x76, 0x3d, 0x12, 0x71, 0x92, 0xf6, 0xe7, 0xe4, 0x5a, 0x20, 0x48, 0x3b, 0x92, 0x22, 0xec,
0x4b, 0xb1, 0x77, 0xde, 0x9f, 0x97, 0x1c, 0xf9, 0x2d, 0xec, 0xc3, 0x7e, 0x48, 0x23, 0x57, 0x5a,
0xde, 0x90, 0x4b, 0x37, 0x25, 0xe5, 0xb9, 0x30, 0xff, 0x53, 0x98, 0x57, 0xb6, 0xb1, 0x7e, 0x73,
0xbd, 0xbe, 0xd1, 0xda, 0x7a, 0x7b, 0x33, 0x47, 0x63, 0x53, 0x99, 0xb7, 0x17, 0x9d, 0xc6, 0x69,
0x88, 0x39, 0x8d, 0xa3, 0x03, 0xc2, 0x18, 0x3e, 0x23, 0x4e, 0x36, 0x07, 0xed, 0x41, 0x2b, 0x22,
0xaf, 0xdd, 0x4c, 0x05, 0x48, 0x15, 0x1b, 0x63, 0x2a, 0x8e, 0x5e, 0xc5, 0x29, 0x9f, 0xa0, 0x07,
0x22, 0xf2, 0xfa, 0xa5, 0x56, 0xf5, 0x02, 0x16, 0x7d, 0x12, 0x10, 0x4e, 0xfc, 0x5c, 0x5d, 0xeb,
0x86, 0xea, 0x3a, 0x5a, 0x41, 0xa6, 0xf2, 0x1d, 0xe8, 0xbc, 0xc2, 0xcc, 0x8d, 0xe2, 0x5c, 0xe3,
0xc2, 0xba, 0xb5, 0xd1, 0x70, 0x16, 0x5e, 0x61, 0x76, 0x18, 0x67, 0x52, 0x4f, 0xa1, 0x49, 0x3c,
0x97, 0xbd, 0xc2, 0xa9, 0xcf, 0xfa, 0x5d, 0xb9, 0xe4, 0xa3, 0xb1, 0x25, 0x77, 0xbd, 0x23, 0x21,
0x30, 0x61, 0xd1, 0x06, 0x51, 0x2c, 0x86, 0x0e, 0xa1, 0x2d, 0xc0, 0x28, 0x94, 0xf5, 0x6e, 0xac,
0x4c, 0xa0, 0xb9, 0x9b, 0xe9, 0x7b, 0x09, 0xbd, 0x0c, 0x91, 0x42, 0x27, 0xba, 0xb1, 0xce, 0x0c,
0xd6, 0x5c, 0xef, 0x7b, 0xd0, 0xd5, 0xb0, 0x14, 0x6a, 0x97, 0x24, 0x30, 0x6d, 0x09, 0x4c, 0x26,
0x68, 0xff, 0xbe, 0x06, 0xbd, 0xfc, 0x36, 0x38, 0x84, 0x25, 0x71, 0xc4, 0x08, 0x7a, 0x04, 0x3d,
0x7d, 0x9c, 0x19, 0xfd, 0x86, 0xb8, 0x01, 0x0d, 0x29, 0x97, 0x97, 0x64, 0xc6, 0x59, 0x54, 0x8c,
0x23, 0xfa, 0x0d, 0xd9, 0x17, 0x64, 0xb4, 0x02, 0x73, 0x01, 0xc1, 0x3e, 0x49, 0xe5, 0x9d, 0x69,
0x3a, 0x7a, 0x84, 0xde, 0x83, 0xc5, 0x90, 0xf0, 0x94, 0x7a, 0xcc, 0xc5, 0xbe, 0x9f, 0x12, 0xc6,
0xf4, 0xd5, 0xe9, 0x68, 0xf2, 0xb6, 0xa2, 0xa2, 0x8f, 0xa1, 0x9f, 0x09, 0x52, 0x71, 0xc6, 0x2f,
0x70, 0xe0, 0x32, 0xe2, 0xc5, 0x91, 0xcf, 0xf4, 0x3d, 0x5a, 0xd1, 0xfc, 0x3d, 0xcd, 0x3e, 0x52,
0x5c, 0xf4, 0x04, 0xba, 0x8c, 0xc7, 0x29, 0x3e, 0x23, 0xee, 0x09, 0xf6, 0xce, 0x89, 0x98, 0x31,
0x2b, 0xc1, 0x5b, 0x35, 0xc0, 0x3b, 0x52, 0x22, 0x8f, 0x95, 0x84, 0xb3, 0xc8, 0x4a, 0x63, 0x66,
0x7f, 0x57, 0x87, 0xfe, 0xb4, 0x6b, 0x20, 0xe3, 0x83, 0x2f, 0xb7, 0xde, 0x76, 0x6a, 0xd4, 0x17,
0xf7, 0x4f, 0x40, 0x22, 0xf7, 0x3a, 0xe3, 0xc8, 0x6f, 0x74, 0x1f, 0xc0, 0x8b, 0x83, 0x80, 0x78,
0x62, 0xa2, 0xde, 0xa4, 0x41, 0x11, 0xf7, 0x53, 0x5e, 0xf9, 0x22, 0x34, 0xcc, 0x38, 0x4d, 0x41,
0x51, 0x51, 0xe1, 0x01, 0x2c, 0x28, 0xf7, 0x69, 0x01, 0x15, 0x15, 0x5a, 0x8a, 0xa6, 0x44, 0xde,
0x07, 0x94, 0x1d, 0x93, 0x93, 0x51, 0x2e, 0x38, 0x27, 0x05, 0xbb, 0x9a, 0xf3, 0x78, 0x94, 0x49,
0xbf, 0x05, 0xcd, 0x94, 0x60, 0xdf, 0x8d, 0xa3, 0x60, 0x24, 0x03, 0x45, 0xc3, 0x69, 0x08, 0xc2,
0x17, 0x51, 0x30, 0x42, 0xff, 0x07, 0xbd, 0x94, 0x24, 0x01, 0xf5, 0xb0, 0x9b, 0x04, 0xd8, 0x23,
0x21, 0x89, 0xb2, 0x98, 0xd1, 0xd5, 0x8c, 0xe7, 0x19, 0x1d, 0xf5, 0x61, 0xfe, 0x82, 0xa4, 0x4c,
0x6c, 0xab, 0x29, 0x45, 0xb2, 0x21, 0xea, 0x42, 0x9d, 0xf3, 0xa0, 0x0f, 0x92, 0x2a, 0x3e, 0xd1,
0x43, 0xe8, 0x7a, 0x71, 0x98, 0x60, 0x8f, 0xbb, 0x29, 0xb9, 0xa0, 0x72, 0x52, 0x4b, 0xb2, 0x17,
0x35, 0xdd, 0xd1, 0x64, 0xb1, 0x9d, 0x30, 0xf6, 0xe9, 0x29, 0x25, 0xbe, 0x8b, 0xb9, 0x76, 0xb6,
0xbc, 0xb8, 0x75, 0xa7, 0x9b, 0x71, 0xb6, 0xb9, 0x72, 0x33, 0xda, 0x84, 0xa5, 0x94, 0x84, 0x31,
0x27, 0x6e, 0xe6, 0xec, 0x08, 0x87, 0xa4, 0xdf, 0x96, 0x38, 0xf7, 0x14, 0x4b, 0xfb, 0xf8, 0x10,
0x87, 0x44, 0x68, 0xaf, 0xc8, 0x8b, 0x58, 0xdb, 0x91, 0xe2, 0xdd, 0x92, 0xf8, 0x33, 0x32, 0xb2,
0xff, 0x66, 0xc1, 0xbd, 0x2b, 0x43, 0xce, 0xd8, 0x11, 0xb8, 0xce, 0xdd, 0x3f, 0x16, 0xc2, 0xf6,
0x10, 0xd6, 0xae, 0x09, 0x04, 0xd7, 0xd8, 0x5a, 0x1b, 0xb3, 0xd5, 0x86, 0x36, 0xf1, 0x5c, 0x1a,
0xf9, 0xe4, 0xd2, 0x3d, 0xa1, 0x5c, 0x5d, 0xd1, 0xb6, 0xd3, 0x22, 0xde, 0x9e, 0xa0, 0x3d, 0xa6,
0x9c, 0xd9, 0xdf, 0x5a, 0xd0, 0x29, 0xdf, 0x21, 0x71, 0x0b, 0xf8, 0x28, 0x21, 0x3a, 0x6f, 0xca,
0x6f, 0xbd, 0x74, 0x4d, 0x67, 0x52, 0x1f, 0xed, 0x01, 0x24, 0x69, 0x9c, 0x90, 0x94, 0x53, 0x22,
0xf4, 0x8a, 0x6b, 0xf9, 0x70, 0xea, 0xb5, 0xdc, 0x7c, 0x9e, 0xcb, 0xee, 0x46, 0x3c, 0x1d, 0x39,
0xc6, 0xe4, 0xc1, 0xa7, 0xb0, 0x58, 0x61, 0x0b, 0x74, 0x84, 0x57, 0x95, 0x01, 0xe2, 0x13, 0x2d,
0xc3, 0xec, 0x05, 0x0e, 0x86, 0x44, 0x9b, 0xa0, 0x06, 0xbf, 0xa8, 0x7d, 0x6c, 0xd9, 0xf3, 0x30,
0xbb, 0x1b, 0x26, 0x7c, 0x24, 0x76, 0xb2, 0x78, 0x34, 0x4c, 0x48, 0xfa, 0x38, 0x88, 0xbd, 0xf3,
0xdd, 0x4b, 0x9e, 0x62, 0xf4, 0x05, 0x74, 0x48, 0x8a, 0xd9, 0x30, 0x15, 0xb7, 0xca, 0xa7, 0xd1,
0x99, 0xd4, 0x59, 0x4e, 0x49, 0x95, 0x39, 0x9b, 0xbb, 0x6a, 0xc2, 0x8e, 0x94, 0x77, 0xda, 0xc4,
0x1c, 0x0e, 0xbe, 0x82, 0x76, 0x89, 0x2f, 0xc0, 0x12, 0x09, 0x5c, 0x7b, 0x45, 0x7e, 0x8b, 0xa0,
0x99, 0xe0, 0x94, 0xf2, 0x91, 0x2e, 0x34, 0xf4, 0x48, 0x84, 0x0a, 0x1d, 0x78, 0xa9, 0xaf, 0x40,
0x6b, 0x3b, 0x4d, 0x45, 0xd9, 0xf3, 0x99, 0xfd, 0x14, 0x96, 0x9f, 0x11, 0x92, 0xec, 0xc4, 0x51,
0x44, 0x3c, 0x4e, 0x7c, 0x87, 0xfc, 0x76, 0x48, 0x18, 0x17, 0x4b, 0xc8, 0x3b, 0xa1, 0xfd, 0x21,
0xbe, 0x45, 0x14, 0x38, 0x4b, 0x13, 0xcf, 0x35, 0xca, 0x99, 0x86, 0x20, 0x88, 0x9a, 0xc0, 0xfe,
0xab, 0x05, 0x1d, 0x75, 0x96, 0xf6, 0x63, 0x4f, 0x9e, 0x20, 0x81, 0xa8, 0x28, 0x6f, 0x34, 0xa2,
0xc3, 0x34, 0xa8, 0xd4, 0x3d, 0xb5, 0x6a, 0xdd, 0xb3, 0x0a, 0x0d, 0x59, 0x18, 0x14, 0x96, 0xce,
0x8b, 0x5c, 0x4f, 0x7d, 0x56, 0x84, 0x34, 0x5f, 0xb1, 0x67, 0x24, 0xbb, 0x95, 0xe5, 0x6e, 0x21,
0x52, 0xa4, 0x8d, 0x59, 0x33, 0x6d, 0xd8, 0xc7, 0xb0, 0xb4, 0x1f, 0xc7, 0xe7, 0xc3, 0x44, 0x99,
0x97, 0xed, 0xb0, 0x0c, 0x8c, 0xb5, 0x5e, 0x17, 0xb6, 0xe4, 0xc0, 0x5c, 0x77, 0xce, 0xed, 0xff,
0x58, 0xb0, 0x5c, 0x56, 0xab, 0x33, 0xdd, 0xd7, 0xb0, 0x94, 0xeb, 0x75, 0x03, 0x8d, 0x85, 0x5a,
0xa0, 0xb5, 0xf5, 0x81, 0x71, 0x06, 0x26, 0xcd, 0xce, 0xaa, 0x27, 0x3f, 0x03, 0xd1, 0xe9, 0x5d,
0x54, 0x28, 0x6c, 0x70, 0x09, 0xdd, 0xaa, 0x98, 0xf0, 0x4d, 0xbe, 0xaa, 0x46, 0xbc, 0x91, 0xcd,
0x44, 0x3f, 0x85, 0x66, 0x61, 0x48, 0x4d, 0x1a, 0xb2, 0x54, 0x32, 0x44, 0xaf, 0x55, 0x48, 0x89,
0xb3, 0x4f, 0xd2, 0x34, 0x4e, 0x75, 0x34, 0x52, 0x03, 0xfb, 0x13, 0x68, 0xfc, 0x60, 0xef, 0xda,
0xff, 0xa8, 0x41, 0x7b, 0x9b, 0x31, 0x7a, 0x16, 0x65, 0x2e, 0x58, 0x86, 0x59, 0x95, 0x77, 0x54,
0x21, 0xa0, 0x06, 0x68, 0x1d, 0x5a, 0x3a, 0xa8, 0x19, 0xd0, 0x9b, 0xa4, 0x6b, 0xe3, 0xa5, 0x0e,
0x74, 0x33, 0xca, 0x34, 0x91, 0x4a, 0x2a, 0x55, 0xf0, 0xec, 0xd4, 0x2a, 0x78, 0xce, 0xa8, 0x82,
0xdf, 0x82, 0xa6, 0x9c, 0x14, 0xc5, 0x3e, 0xd1, 0xe5, 0x71, 0x43, 0x10, 0x0e, 0x63, 0x9f, 0xa0,
0x2d, 0x58, 0x09, 0x49, 0x18, 0xa7, 0x23, 0x37, 0xc4, 0x89, 0x2b, 0x8a, 0x70, 0x59, 0xd8, 0x84,
0x27, 0x3a, 0x30, 0x23, 0xc5, 0x3d, 0xc0, 0xc9, 0x01, 0xbe, 0x14, 0xb5, 0xcd, 0xc1, 0x09, 0xda,
0x82, 0xdb, 0x5f, 0xa6, 0x94, 0xe3, 0x93, 0x80, 0x94, 0x8b, 0x7b, 0x15, 0xa8, 0x97, 0x32, 0xa6,
0x51, 0xe1, 0xdb, 0x7f, 0xb1, 0xa0, 0x93, 0xa1, 0xa6, 0x4f, 0x58, 0x17, 0xea, 0xa7, 0xb9, 0x97,
0xc5, 0x67, 0xe6, 0x8b, 0xda, 0x34, 0x5f, 0x8c, 0x75, 0x18, 0x39, 0xf2, 0x33, 0x26, 0xf2, 0xb9,
0xd3, 0x67, 0x0d, 0xa7, 0x0b, 0x68, 0xf0, 0x90, 0xbf, 0xca, 0xa0, 0x11, 0xdf, 0xf6, 0x19, 0xf4,
0x8e, 0x38, 0xe6, 0x94, 0x71, 0xea, 0xb1, 0xcc, 0x9d, 0x15, 0xc7, 0x59, 0xd7, 0x39, 0xae, 0x36,
0xcd, 0x71, 0xf5, 0xdc, 0x71, 0xf6, 0xbf, 0x2c, 0x40, 0xe6, 0x4a, 0x1a, 0x82, 0x1f, 0x61, 0x29,
0x01, 0x19, 0x8f, 0xb9, 0x28, 0x15, 0x45, 0x39, 0xa6, 0x8b, 0x2a, 0x49, 0x11, 0xee, 0x13, 0xa7,
0x61, 0xc8, 0x88, 0xaf, 0xb8, 0xaa, 0xa2, 0x6a, 0x08, 0x82, 0x64, 0x96, 0x0b, 0xb2, 0xb9, 0x4a,
0x41, 0x66, 0x6f, 0x43, 0x4b, 0x27, 0xa7, 0x63, 0x91, 0xd8, 0xae, 0xb7, 0x5e, 0x5b, 0x57, 0x2b,
0x80, 0x58, 0x07, 0xd8, 0x29, 0xac, 0x9f, 0x10, 0x9e, 0xed, 0xdf, 0xc1, 0xed, 0x42, 0x62, 0x9f,
0x32, 0x9e, 0xf9, 0xe5, 0x23, 0x58, 0xa1, 0x91, 0x17, 0x0c, 0x7d, 0xe2, 0x46, 0x22, 0xbd, 0x07,
0x79, 0x67, 0x63, 0xc9, 0x52, 0x6e, 0x59, 0x73, 0x0f, 0x25, 0x33, 0xeb, 0x70, 0xde, 0x07, 0x94,
0xcd, 0x22, 0x5e, 0x3e, 0xa3, 0x26, 0x67, 0x74, 0x35, 0x67, 0xd7, 0xd3, 0xd2, 0xf6, 0x0b, 0x58,
0xa9, 0x2e, 0xae, 0x5d, 0xf5, 0x73, 0x68, 0x15, 0xb0, 0x67, 0x71, 0xf0, 0xb6, 0x11, 0x7e, 0x8a,
0x79, 0x8e, 0x29, 0x69, 0xff, 0x3f, 0xdc, 0x29, 0x58, 0x4f, 0x64, 0xa0, 0xbf, 0x22, 0x3b, 0xd9,
0x03, 0xe8, 0x8f, 0x8b, 0x2b, 0x1b, 0xec, 0x3f, 0xd7, 0x61, 0xe1, 0x89, 0xbe, 0xb9, 0xa2, 0xc6,
0x31, 0xaa, 0x1a, 0x55, 0x5a, 0x3c, 0x80, 0x85, 0xd2, 0x85, 0x54, 0xc5, 0x78, 0xeb, 0xc2, 0x68,
0xb5, 0x27, 0x35, 0xe5, 0x75, 0x29, 0x56, 0x6d, 0xca, 0x1f, 0x41, 0xef, 0x34, 0x25, 0x64, 0xbc,
0x7f, 0x9f, 0x71, 0x16, 0x05, 0xc3, 0x94, 0xdd, 0x84, 0x25, 0xec, 0x71, 0x7a, 0x51, 0x91, 0x56,
0xe7, 0xab, 0xa7, 0x58, 0xa6, 0xfc, 0xe7, 0xb9, 0xa1, 0x34, 0x3a, 0x8d, 0x59, 0x7f, 0xee, 0xfb,
0xf7, 0xdf, 0x7a, 0x37, 0x82, 0xc3, 0xd0, 0x73, 0xe8, 0x64, 0x7d, 0x9c, 0xd6, 0x34, 0x7f, 0xe3,
0x1e, 0x71, 0x81, 0x14, 0x2c, 0x66, 0x14, 0xd5, 0xa5, 0x9d, 0x34, 0xd4, 0x4e, 0x14, 0xcb, 0x0c,
0x6c, 0xff, 0xac, 0x41, 0xc3, 0xc1, 0xde, 0xf9, 0x9b, 0xed, 0x8f, 0xcf, 0x60, 0x31, 0xcf, 0x11,
0x25, 0x97, 0xdc, 0x31, 0x80, 0x34, 0x8f, 0x9e, 0xd3, 0xf6, 0x8d, 0xd1, 0x54, 0xd8, 0xe6, 0xa7,
0xc1, 0xf6, 0xf7, 0x1a, 0x74, 0x9e, 0xe4, 0x79, 0xeb, 0xcd, 0x06, 0x6f, 0x0b, 0x40, 0x24, 0xda,
0x12, 0x6e, 0x66, 0x61, 0x92, 0x1d, 0x0f, 0xa7, 0x99, 0xea, 0xaf, 0x9b, 0xe3, 0xf5, 0x6d, 0x0d,
0x16, 0x8e, 0xe3, 0x24, 0x0e, 0xe2, 0xb3, 0xd1, 0x9b, 0x8d, 0xd6, 0x2e, 0xf4, 0x8c, 0x1a, 0xa6,
0x04, 0xda, 0x6a, 0xe5, 0xb0, 0x15, 0x87, 0xc3, 0x59, 0xf4, 0x4b, 0xe3, 0x9b, 0x03, 0xb8, 0x04,
0x3d, 0x5d, 0xd7, 0x17, 0x29, 0xc5, 0xfe, 0xa3, 0x05, 0xc8, 0xa4, 0xea, 0x58, 0xff, 0x4b, 0x68,
0x73, 0x8d, 0xb5, 0xb4, 0x4f, 0x77, 0x3e, 0xe6, 0x5d, 0x30, 0x7d, 0xe1, 0x2c, 0x70, 0xd3, 0x33,
0x3f, 0x81, 0xe5, 0xb1, 0x37, 0x22, 0x51, 0x50, 0x29, 0x8f, 0xf4, 0x2a, 0xcf, 0x44, 0x07, 0x27,
0xf6, 0x47, 0x70, 0x5b, 0x15, 0xd1, 0x59, 0x1e, 0xca, 0xf2, 0xc3, 0x58, 0x35, 0xdc, 0x2e, 0xaa,
0x61, 0xfb, 0x3b, 0x0b, 0x56, 0xaa, 0xd3, 0xb4, 0xfd, 0x57, 0xcd, 0x43, 0x18, 0x90, 0x8e, 0x97,
0x66, 0x5d, 0xaf, 0xca, 0xe9, 0x0f, 0xc7, 0xea, 0xfa, 0xaa, 0xee, 0xcd, 0x2c, 0x8e, 0x16, 0xa5,
0x7d, 0x97, 0x95, 0x09, 0x6c, 0x80, 0xa1, 0x37, 0x26, 0x26, 0xba, 0xa2, 0x6c, 0x5d, 0x6d, 0xd3,
0xbc, 0x9e, 0xf8, 0x03, 0x0a, 0x7b, 0x7b, 0x0d, 0xee, 0x3d, 0x25, 0xfc, 0x40, 0xca, 0xec, 0xc4,
0xd1, 0x29, 0x3d, 0x1b, 0xa6, 0x4a, 0xa8, 0x70, 0xed, 0xfd, 0x69, 0x12, 0x1a, 0xa6, 0x09, 0x0f,
0x71, 0xd6, 0x8d, 0x1f, 0xe2, 0x6a, 0x57, 0x3d, 0xc4, 0xd9, 0x9f, 0x40, 0x5f, 0x9c, 0x2c, 0x6d,
0x45, 0x40, 0x49, 0xc4, 0xf3, 0x3a, 0x73, 0x0d, 0x5a, 0x9e, 0xa4, 0xb8, 0xc6, 0x93, 0x01, 0x28,
0x92, 0xa8, 0xaf, 0xec, 0xc7, 0xb0, 0x3a, 0x61, 0xb2, 0x36, 0xfe, 0x5d, 0xe8, 0xc8, 0x2e, 0x56,
0x5b, 0x4e, 0xb2, 0xde, 0xaf, 0x2d, 0xa8, 0xdb, 0x19, 0xd1, 0x0e, 0x61, 0x65, 0x9f, 0x60, 0x46,
0xb6, 0xfd, 0x90, 0x46, 0xc7, 0xf1, 0x39, 0xc9, 0xbb, 0x96, 0x77, 0xa1, 0x93, 0xa4, 0xe4, 0x82,
0xc6, 0x43, 0xe6, 0x72, 0xc1, 0x90, 0x16, 0xd4, 0x9d, 0x76, 0x46, 0x95, 0xd2, 0xa2, 0x7e, 0xca,
0xc5, 0x44, 0xa3, 0xef, 0x72, 0x1a, 0xaa, 0xa7, 0x84, 0xba, 0xd3, 0xcd, 0x38, 0xfb, 0xb1, 0x77,
0x7e, 0x4c, 0x43, 0x62, 0xff, 0xc1, 0x82, 0x3b, 0x63, 0xeb, 0x69, 0x8b, 0xef, 0x01, 0x50, 0xe6,
0xe2, 0x20, 0x88, 0x5f, 0x13, 0x5f, 0xd7, 0x6c, 0x4d, 0xca, 0xb6, 0x15, 0xa1, 0xa8, 0xda, 0x6b,
0x66, 0xd5, 0x7e, 0x17, 0x40, 0xad, 0xca, 0xdc, 0x48, 0x3d, 0xc2, 0xd4, 0x9d, 0x86, 0xa0, 0x1c,
0xb3, 0x43, 0xd9, 0xde, 0x29, 0xd3, 0x67, 0x24, 0x43, 0x0d, 0xec, 0x18, 0xfa, 0x0e, 0x09, 0xfe,
0x87, 0xbb, 0x7e, 0x0b, 0x56, 0x27, 0x2c, 0xa8, 0x8b, 0xb6, 0x7d, 0xb8, 0xf3, 0x92, 0xa4, 0xf4,
0x74, 0x34, 0x6e, 0x4c, 0x6e, 0xbe, 0x65, 0x98, 0x2f, 0x6e, 0x6f, 0x75, 0x49, 0xb5, 0x63, 0xb1,
0xd4, 0xcf, 0xa0, 0x3f, 0xae, 0x4d, 0x03, 0xbc, 0x0a, 0x0d, 0xca, 0xdc, 0x0b, 0x1c, 0xd0, 0x0c,
0xde, 0x79, 0xca, 0x5e, 0x8a, 0xe1, 0xd6, 0xbf, 0x9b, 0x30, 0x7f, 0x44, 0xf0, 0x6b, 0x42, 0x7c,
0xb4, 0x07, 0xed, 0x23, 0x12, 0xf9, 0xc5, 0xaf, 0x9e, 0x65, 0xe3, 0xae, 0xe5, 0xd4, 0xc1, 0xdd,
0x49, 0xd4, 0x7c, 0x57, 0xb7, 0x36, 0xac, 0x0f, 0x2c, 0xf4, 0x02, 0xda, 0xa5, 0x67, 0x17, 0xb4,
0x66, 0x4c, 0x9a, 0xf4, 0x20, 0x33, 0x58, 0x1d, 0x2b, 0xcc, 0xb2, 0xdb, 0x9d, 0xab, 0x5c, 0x30,
0x5f, 0x14, 0xd0, 0xfd, 0xa9, 0x4f, 0x0d, 0x4a, 0xe1, 0xda, 0x35, 0x4f, 0x11, 0xf6, 0x2d, 0xf4,
0x19, 0xcc, 0xa9, 0xd6, 0x13, 0xf5, 0x0d, 0xe1, 0x52, 0x0f, 0x5f, 0xb2, 0xab, 0xdc, 0xa7, 0xda,
0xb7, 0xd0, 0x33, 0x80, 0xa2, 0x79, 0x43, 0x77, 0x4b, 0x6f, 0x75, 0x95, 0xee, 0x71, 0x70, 0x6f,
0x0a, 0x37, 0x57, 0xf6, 0x25, 0x74, 0xca, 0x2d, 0x06, 0x5a, 0x9f, 0xd8, 0x45, 0x18, 0x79, 0x6a,
0xf0, 0xe0, 0x0a, 0x89, 0x5c, 0xf1, 0x6f, 0xa0, 0x5b, 0xed, 0x1c, 0x90, 0x3d, 0x71, 0x62, 0xa9,
0x0b, 0x19, 0xbc, 0x7d, 0xa5, 0x8c, 0x09, 0x42, 0x91, 0x2a, 0x4b, 0x20, 0x8c, 0xe5, 0xd5, 0x12,
0x08, 0xe3, 0xf9, 0x55, 0x81, 0x50, 0xce, 0x2f, 0x25, 0x10, 0x26, 0x66, 0xc3, 0x12, 0x08, 0x93,
0x93, 0x93, 0x7d, 0x0b, 0xc5, 0xb0, 0x32, 0x39, 0xea, 0x23, 0xf3, 0xdd, 0xf2, 0xca, 0xd4, 0x31,
0x78, 0xf8, 0x3d, 0x24, 0xf3, 0x05, 0xbf, 0x86, 0xde, 0x58, 0x90, 0x46, 0x26, 0xa4, 0xd3, 0xe2,
0xff, 0xe0, 0x9d, 0xab, 0x85, 0xf2, 0x15, 0xbe, 0x82, 0xc5, 0x4a, 0x48, 0x45, 0x25, 0x28, 0x26,
0x06, 0xba, 0x81, 0x7d, 0x95, 0x88, 0x69, 0xfd, 0x58, 0xe4, 0x2a, 0x59, 0x3f, 0x2d, 0x90, 0x96,
0xac, 0x9f, 0x1e, 0xfc, 0xe4, 0xa9, 0xac, 0x06, 0xac, 0xd2, 0xa9, 0x9c, 0x12, 0x1b, 0x4b, 0xa7,
0x72, 0x5a, 0xc4, 0xb3, 0x6f, 0x9d, 0xcc, 0xc9, 0xdf, 0xd8, 0x1f, 0xfe, 0x37, 0x00, 0x00, 0xff,
0xff, 0x41, 0x4f, 0x53, 0xa0, 0xd6, 0x1e, 0x00, 0x00,
} }

107
weed/server/master_grpc_server_admin.go

@ -0,0 +1,107 @@
package weed_server
import (
"context"
"math/rand"
"time"
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
)
/*
How exclusive lock works?
-----------
Shell
------
When shell lock,
* lease an admin token (lockTime, token)
* start a goroutine to renew the admin token periodically
For later volume operations, send (lockTime, token) to volume servers for exclusive access
* need to pause renewal a few seconds, to prevent race condition
When shell unlock
* stop the renewal goroutine
* sends a release lock request
Master
------
Master maintains:
* randomNumber
* lastLockTime
When master receives the lease/renew request from shell
If lastLockTime still fresh {
if is a renew and token is valid {
// for renew
generate the randomNumber => token
return
}
refuse
return
} else {
// for fresh lease request
generate the randomNumber => token
return
}
When master receives the release lock request from shell
set the lastLockTime to zero
When master receives the verfication request from volume servers
return secret+lockTime == token && lockTime == lastLockTime
Volume
------
When receives (lockTime, token), ask the master whether this is valid
*/
const (
LockDuration = 10 * time.Second
)
func (ms *MasterServer) LeaseAdminToken(ctx context.Context, req *master_pb.LeaseAdminTokenRequest) (*master_pb.LeaseAdminTokenResponse, error) {
resp := &master_pb.LeaseAdminTokenResponse{}
if ms.adminAccessLockTime.Add(LockDuration).After(time.Now()) {
if req.PreviousToken != 0 && ms.isValidToken(time.Unix(0, req.PreviousLockTime), req.PreviousToken) {
// for renew
ts, token := ms.generateToken()
resp.Token, resp.LockTsNs = token, ts.UnixNano()
return resp, nil
}
// refuse since still locked
resp.Error = "already locked"
return resp, nil
}
// for fresh lease request
ts, token := ms.generateToken()
resp.Token, resp.LockTsNs = token, ts.UnixNano()
return resp, nil
}
func (ms *MasterServer) isValidToken(ts time.Time, token int64) bool {
return ms.adminAccessLockTime.Equal(ts) && ms.adminAccessSecret == token
}
func (ms *MasterServer) generateToken() (ts time.Time, token int64) {
ms.adminAccessLockTime = time.Now()
ms.adminAccessSecret = rand.Int63()
return ms.adminAccessLockTime, ms.adminAccessSecret
}
func (ms *MasterServer) ReleaseAdminToken(ctx context.Context, req *master_pb.ReleaseAdminTokenRequest) (*master_pb.ReleaseAdminTokenResponse, error) {
resp := &master_pb.ReleaseAdminTokenResponse{}
if ms.isValidToken(time.Unix(0, req.PreviousLockTime), req.PreviousToken) {
ms.adminAccessSecret = 0
}
return resp, nil
}
func (ms *MasterServer) VerifyAdminToken(ctx context.Context, req *master_pb.VerifyAdminTokenRequest) (*master_pb.VerifyAdminTokenResponse, error) {
resp := &master_pb.VerifyAdminTokenResponse{}
if ms.isValidToken(time.Unix(0, req.LockTime), req.Token) {
resp.IsValid = true
}
return resp, nil
}

3
weed/server/master_server.go

@ -66,7 +66,8 @@ type MasterServer struct {
MasterClient *wdclient.MasterClient MasterClient *wdclient.MasterClient
currentAdminShellClient string
adminAccessSecret int64
adminAccessLockTime time.Time
} }
func NewMasterServer(r *mux.Router, option *MasterOption, peers []string) *MasterServer { func NewMasterServer(r *mux.Router, option *MasterOption, peers []string) *MasterServer {

Loading…
Cancel
Save