1
0
Fork 0
mirror of https://github.com/chrislusf/seaweedfs synced 2024-07-04 08:06:53 +02:00
This commit is contained in:
Chris Lu 2019-11-27 03:09:42 -08:00
parent 67e5f5b558
commit 0f9ba84274
10 changed files with 571 additions and 176 deletions

View file

@ -0,0 +1,44 @@
package pb
import (
"fmt"
"testing"
"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
"github.com/golang/protobuf/jsonpb"
)
func TestJsonpMarshalUnmarshal(t *testing.T) {
tv := &volume_server_pb.TieredVolume{
BackendType: "aws",
BackendName: "",
Version: 12,
}
m := jsonpb.Marshaler{
EmitDefaults: true,
Indent: " ",
}
if text, err := m.MarshalToString(tv); err != nil {
fmt.Printf("marshal eror: %v\n", err)
} else {
fmt.Printf("marshalled: %s\n", text)
}
rawJson := `{
"backendType":"aws",
"backendName":"temp",
"version":12
}`
tv1 := &volume_server_pb.TieredVolume{}
if err := jsonpb.UnmarshalString(rawJson, tv1); err != nil {
fmt.Printf("unmarshal eror: %v\n", err)
}
fmt.Printf("unmarshalled: %+v\n", tv1)
}

View file

@ -67,6 +67,10 @@ service VolumeServer {
rpc VolumeEcBlobDelete (VolumeEcBlobDeleteRequest) returns (VolumeEcBlobDeleteResponse) {
}
// tiered storage
rpc VolumeTierCopyDatToRemote (VolumeTierCopyDatToRemoteRequest) returns (VolumeTierCopyDatToRemoteResponse) {
}
// query
rpc Query (QueryRequest) returns (stream QueriedStripe) {
}
@ -324,6 +328,22 @@ message MemStatus {
uint64 stack = 7;
}
// tired storage on volume servers
message TieredVolume {
string backend_type = 1;
string backend_name = 2;
uint64 version = 3;
}
message VolumeTierCopyDatToRemoteRequest {
uint32 volume_id = 1;
string collection = 2;
string destination = 3;
}
message VolumeTierCopyDatToRemoteResponse {
}
// select on volume servers
message QueryRequest {
repeated string selections = 1;
repeated string from_file_ids = 2;

View file

@ -65,6 +65,9 @@ It has these top-level messages:
ReadVolumeFileStatusResponse
DiskStatus
MemStatus
TieredVolume
VolumeTierCopyDatToRemoteRequest
VolumeTierCopyDatToRemoteResponse
QueryRequest
QueriedStripe
*/
@ -1394,6 +1397,76 @@ func (m *MemStatus) GetStack() uint64 {
return 0
}
// tired storage on volume servers
type TieredVolume struct {
BackendType string `protobuf:"bytes,1,opt,name=backend_type,json=backendType" json:"backend_type,omitempty"`
BackendName string `protobuf:"bytes,2,opt,name=backend_name,json=backendName" json:"backend_name,omitempty"`
Version uint64 `protobuf:"varint,3,opt,name=version" json:"version,omitempty"`
}
func (m *TieredVolume) Reset() { *m = TieredVolume{} }
func (m *TieredVolume) String() string { return proto.CompactTextString(m) }
func (*TieredVolume) ProtoMessage() {}
func (*TieredVolume) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{56} }
func (m *TieredVolume) GetBackendType() string {
if m != nil {
return m.BackendType
}
return ""
}
func (m *TieredVolume) GetBackendName() string {
if m != nil {
return m.BackendName
}
return ""
}
func (m *TieredVolume) GetVersion() uint64 {
if m != nil {
return m.Version
}
return 0
}
type VolumeTierCopyDatToRemoteRequest struct {
VolumeId uint32 `protobuf:"varint,1,opt,name=volume_id,json=volumeId" json:"volume_id,omitempty"`
Collection string `protobuf:"bytes,2,opt,name=collection" json:"collection,omitempty"`
}
func (m *VolumeTierCopyDatToRemoteRequest) Reset() { *m = VolumeTierCopyDatToRemoteRequest{} }
func (m *VolumeTierCopyDatToRemoteRequest) String() string { return proto.CompactTextString(m) }
func (*VolumeTierCopyDatToRemoteRequest) ProtoMessage() {}
func (*VolumeTierCopyDatToRemoteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{57}
}
func (m *VolumeTierCopyDatToRemoteRequest) GetVolumeId() uint32 {
if m != nil {
return m.VolumeId
}
return 0
}
func (m *VolumeTierCopyDatToRemoteRequest) GetCollection() string {
if m != nil {
return m.Collection
}
return ""
}
type VolumeTierCopyDatToRemoteResponse struct {
}
func (m *VolumeTierCopyDatToRemoteResponse) Reset() { *m = VolumeTierCopyDatToRemoteResponse{} }
func (m *VolumeTierCopyDatToRemoteResponse) String() string { return proto.CompactTextString(m) }
func (*VolumeTierCopyDatToRemoteResponse) ProtoMessage() {}
func (*VolumeTierCopyDatToRemoteResponse) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{58}
}
// select on volume servers
type QueryRequest struct {
Selections []string `protobuf:"bytes,1,rep,name=selections" json:"selections,omitempty"`
FromFileIds []string `protobuf:"bytes,2,rep,name=from_file_ids,json=fromFileIds" json:"from_file_ids,omitempty"`
@ -1405,7 +1478,7 @@ type QueryRequest struct {
func (m *QueryRequest) Reset() { *m = QueryRequest{} }
func (m *QueryRequest) String() string { return proto.CompactTextString(m) }
func (*QueryRequest) ProtoMessage() {}
func (*QueryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{56} }
func (*QueryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{59} }
func (m *QueryRequest) GetSelections() []string {
if m != nil {
@ -1451,7 +1524,7 @@ type QueryRequest_Filter struct {
func (m *QueryRequest_Filter) Reset() { *m = QueryRequest_Filter{} }
func (m *QueryRequest_Filter) String() string { return proto.CompactTextString(m) }
func (*QueryRequest_Filter) ProtoMessage() {}
func (*QueryRequest_Filter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{56, 0} }
func (*QueryRequest_Filter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{59, 0} }
func (m *QueryRequest_Filter) GetField() string {
if m != nil {
@ -1486,7 +1559,7 @@ func (m *QueryRequest_InputSerialization) Reset() { *m = QueryRequest_In
func (m *QueryRequest_InputSerialization) String() string { return proto.CompactTextString(m) }
func (*QueryRequest_InputSerialization) ProtoMessage() {}
func (*QueryRequest_InputSerialization) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{56, 1}
return fileDescriptor0, []int{59, 1}
}
func (m *QueryRequest_InputSerialization) GetCompressionType() string {
@ -1534,7 +1607,7 @@ func (m *QueryRequest_InputSerialization_CSVInput) Reset() {
func (m *QueryRequest_InputSerialization_CSVInput) String() string { return proto.CompactTextString(m) }
func (*QueryRequest_InputSerialization_CSVInput) ProtoMessage() {}
func (*QueryRequest_InputSerialization_CSVInput) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{56, 1, 0}
return fileDescriptor0, []int{59, 1, 0}
}
func (m *QueryRequest_InputSerialization_CSVInput) GetFileHeaderInfo() string {
@ -1596,7 +1669,7 @@ func (m *QueryRequest_InputSerialization_JSONInput) Reset() {
func (m *QueryRequest_InputSerialization_JSONInput) String() string { return proto.CompactTextString(m) }
func (*QueryRequest_InputSerialization_JSONInput) ProtoMessage() {}
func (*QueryRequest_InputSerialization_JSONInput) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{56, 1, 1}
return fileDescriptor0, []int{59, 1, 1}
}
func (m *QueryRequest_InputSerialization_JSONInput) GetType() string {
@ -1617,7 +1690,7 @@ func (m *QueryRequest_InputSerialization_ParquetInput) String() string {
}
func (*QueryRequest_InputSerialization_ParquetInput) ProtoMessage() {}
func (*QueryRequest_InputSerialization_ParquetInput) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{56, 1, 2}
return fileDescriptor0, []int{59, 1, 2}
}
type QueryRequest_OutputSerialization struct {
@ -1629,7 +1702,7 @@ func (m *QueryRequest_OutputSerialization) Reset() { *m = QueryRequest_O
func (m *QueryRequest_OutputSerialization) String() string { return proto.CompactTextString(m) }
func (*QueryRequest_OutputSerialization) ProtoMessage() {}
func (*QueryRequest_OutputSerialization) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{56, 2}
return fileDescriptor0, []int{59, 2}
}
func (m *QueryRequest_OutputSerialization) GetCsvOutput() *QueryRequest_OutputSerialization_CSVOutput {
@ -1662,7 +1735,7 @@ func (m *QueryRequest_OutputSerialization_CSVOutput) String() string {
}
func (*QueryRequest_OutputSerialization_CSVOutput) ProtoMessage() {}
func (*QueryRequest_OutputSerialization_CSVOutput) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{56, 2, 0}
return fileDescriptor0, []int{59, 2, 0}
}
func (m *QueryRequest_OutputSerialization_CSVOutput) GetQuoteFields() string {
@ -1712,7 +1785,7 @@ func (m *QueryRequest_OutputSerialization_JSONOutput) String() string {
}
func (*QueryRequest_OutputSerialization_JSONOutput) ProtoMessage() {}
func (*QueryRequest_OutputSerialization_JSONOutput) Descriptor() ([]byte, []int) {
return fileDescriptor0, []int{56, 2, 1}
return fileDescriptor0, []int{59, 2, 1}
}
func (m *QueryRequest_OutputSerialization_JSONOutput) GetRecordDelimiter() string {
@ -1729,7 +1802,7 @@ type QueriedStripe struct {
func (m *QueriedStripe) Reset() { *m = QueriedStripe{} }
func (m *QueriedStripe) String() string { return proto.CompactTextString(m) }
func (*QueriedStripe) ProtoMessage() {}
func (*QueriedStripe) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{57} }
func (*QueriedStripe) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{60} }
func (m *QueriedStripe) GetRecords() []byte {
if m != nil {
@ -1795,6 +1868,9 @@ func init() {
proto.RegisterType((*ReadVolumeFileStatusResponse)(nil), "volume_server_pb.ReadVolumeFileStatusResponse")
proto.RegisterType((*DiskStatus)(nil), "volume_server_pb.DiskStatus")
proto.RegisterType((*MemStatus)(nil), "volume_server_pb.MemStatus")
proto.RegisterType((*TieredVolume)(nil), "volume_server_pb.TieredVolume")
proto.RegisterType((*VolumeTierCopyDatToRemoteRequest)(nil), "volume_server_pb.VolumeTierCopyDatToRemoteRequest")
proto.RegisterType((*VolumeTierCopyDatToRemoteResponse)(nil), "volume_server_pb.VolumeTierCopyDatToRemoteResponse")
proto.RegisterType((*QueryRequest)(nil), "volume_server_pb.QueryRequest")
proto.RegisterType((*QueryRequest_Filter)(nil), "volume_server_pb.QueryRequest.Filter")
proto.RegisterType((*QueryRequest_InputSerialization)(nil), "volume_server_pb.QueryRequest.InputSerialization")
@ -1847,6 +1923,8 @@ type VolumeServerClient interface {
VolumeEcShardsUnmount(ctx context.Context, in *VolumeEcShardsUnmountRequest, opts ...grpc.CallOption) (*VolumeEcShardsUnmountResponse, error)
VolumeEcShardRead(ctx context.Context, in *VolumeEcShardReadRequest, opts ...grpc.CallOption) (VolumeServer_VolumeEcShardReadClient, error)
VolumeEcBlobDelete(ctx context.Context, in *VolumeEcBlobDeleteRequest, opts ...grpc.CallOption) (*VolumeEcBlobDeleteResponse, error)
// tiered storage
VolumeTierCopyDatToRemote(ctx context.Context, in *VolumeTierCopyDatToRemoteRequest, opts ...grpc.CallOption) (*VolumeTierCopyDatToRemoteResponse, error)
// query
Query(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (VolumeServer_QueryClient, error)
}
@ -2185,6 +2263,15 @@ func (c *volumeServerClient) VolumeEcBlobDelete(ctx context.Context, in *VolumeE
return out, nil
}
func (c *volumeServerClient) VolumeTierCopyDatToRemote(ctx context.Context, in *VolumeTierCopyDatToRemoteRequest, opts ...grpc.CallOption) (*VolumeTierCopyDatToRemoteResponse, error) {
out := new(VolumeTierCopyDatToRemoteResponse)
err := grpc.Invoke(ctx, "/volume_server_pb.VolumeServer/VolumeTierCopyDatToRemote", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *volumeServerClient) Query(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (VolumeServer_QueryClient, error) {
stream, err := grpc.NewClientStream(ctx, &_VolumeServer_serviceDesc.Streams[4], c.cc, "/volume_server_pb.VolumeServer/Query", opts...)
if err != nil {
@ -2249,6 +2336,8 @@ type VolumeServerServer interface {
VolumeEcShardsUnmount(context.Context, *VolumeEcShardsUnmountRequest) (*VolumeEcShardsUnmountResponse, error)
VolumeEcShardRead(*VolumeEcShardReadRequest, VolumeServer_VolumeEcShardReadServer) error
VolumeEcBlobDelete(context.Context, *VolumeEcBlobDeleteRequest) (*VolumeEcBlobDeleteResponse, error)
// tiered storage
VolumeTierCopyDatToRemote(context.Context, *VolumeTierCopyDatToRemoteRequest) (*VolumeTierCopyDatToRemoteResponse, error)
// query
Query(*QueryRequest, VolumeServer_QueryServer) error
}
@ -2737,6 +2826,24 @@ func _VolumeServer_VolumeEcBlobDelete_Handler(srv interface{}, ctx context.Conte
return interceptor(ctx, in, info, handler)
}
func _VolumeServer_VolumeTierCopyDatToRemote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(VolumeTierCopyDatToRemoteRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(VolumeServerServer).VolumeTierCopyDatToRemote(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/volume_server_pb.VolumeServer/VolumeTierCopyDatToRemote",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VolumeServerServer).VolumeTierCopyDatToRemote(ctx, req.(*VolumeTierCopyDatToRemoteRequest))
}
return interceptor(ctx, in, info, handler)
}
func _VolumeServer_Query_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(QueryRequest)
if err := stream.RecvMsg(m); err != nil {
@ -2850,6 +2957,10 @@ var _VolumeServer_serviceDesc = grpc.ServiceDesc{
MethodName: "VolumeEcBlobDelete",
Handler: _VolumeServer_VolumeEcBlobDelete_Handler,
},
{
MethodName: "VolumeTierCopyDatToRemote",
Handler: _VolumeServer_VolumeTierCopyDatToRemote_Handler,
},
},
Streams: []grpc.StreamDesc{
{
@ -2884,162 +2995,167 @@ var _VolumeServer_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("volume_server.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 2503 bytes of a gzipped FileDescriptorProto
// 2590 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xd4, 0x1a, 0x4d, 0x77, 0x1c, 0x47,
0x51, 0xeb, 0x5d, 0x49, 0xbb, 0xb5, 0x2b, 0x4b, 0x6e, 0xc9, 0xd2, 0x7a, 0x6c, 0xc9, 0xca, 0xe4,
0xc3, 0xb2, 0x9d, 0xc8, 0x8e, 0x02, 0x24, 0x24, 0x04, 0xb0, 0x65, 0x1b, 0x4c, 0x62, 0x99, 0x8c,
0x1c, 0x13, 0x70, 0x1e, 0xf3, 0x5a, 0x33, 0x2d, 0x6b, 0xd0, 0xcc, 0xf4, 0x78, 0xa6, 0x47, 0xd6,
0xfa, 0xc1, 0x29, 0x5c, 0xf9, 0x01, 0x9c, 0x39, 0x71, 0xe1, 0xca, 0x0f, 0xe0, 0xc2, 0x0f, 0x80,
0x2b, 0x17, 0xce, 0x1c, 0xb8, 0xf1, 0x1e, 0x17, 0x5e, 0x7f, 0xcc, 0xec, 0x7c, 0x6a, 0x47, 0xb1,
0xdf, 0xe3, 0xe5, 0xd6, 0x53, 0x5d, 0x1f, 0x5d, 0xd5, 0x55, 0xd5, 0xd5, 0xd5, 0x03, 0x8b, 0x47,
0xd4, 0x8d, 0x3d, 0x62, 0x46, 0x24, 0x3c, 0x22, 0xe1, 0x66, 0x10, 0x52, 0x46, 0xd1, 0x42, 0x0e,
0x68, 0x06, 0x7b, 0xfa, 0x0d, 0x40, 0xb7, 0x31, 0xb3, 0x0e, 0xee, 0x10, 0x97, 0x30, 0x62, 0x90,
0x67, 0x31, 0x89, 0x18, 0xba, 0x00, 0xdd, 0x7d, 0xc7, 0x25, 0xa6, 0x63, 0x47, 0xc3, 0xd6, 0x7a,
0x7b, 0xa3, 0x67, 0xcc, 0xf2, 0xef, 0xfb, 0x76, 0xa4, 0x3f, 0x84, 0xc5, 0x1c, 0x41, 0x14, 0x50,
0x3f, 0x22, 0xe8, 0x03, 0x98, 0x0d, 0x49, 0x14, 0xbb, 0x4c, 0x12, 0xf4, 0xb7, 0xd6, 0x36, 0x8b,
0xb2, 0x36, 0x53, 0x92, 0xd8, 0x65, 0x46, 0x82, 0xae, 0x7f, 0xd5, 0x82, 0x41, 0x76, 0x06, 0xad,
0xc0, 0xac, 0x12, 0x3e, 0x6c, 0xad, 0xb7, 0x36, 0x7a, 0xc6, 0x8c, 0x94, 0x8d, 0x96, 0x61, 0x26,
0x62, 0x98, 0xc5, 0xd1, 0xf0, 0xcc, 0x7a, 0x6b, 0x63, 0xda, 0x50, 0x5f, 0x68, 0x09, 0xa6, 0x49,
0x18, 0xd2, 0x70, 0xd8, 0x16, 0xe8, 0xf2, 0x03, 0x21, 0xe8, 0x44, 0xce, 0x0b, 0x32, 0xec, 0xac,
0xb7, 0x36, 0xe6, 0x0c, 0x31, 0x46, 0x43, 0x98, 0x3d, 0x22, 0x61, 0xe4, 0x50, 0x7f, 0x38, 0x2d,
0xc0, 0xc9, 0xa7, 0x3e, 0x0b, 0xd3, 0x77, 0xbd, 0x80, 0x8d, 0xf4, 0xf7, 0x61, 0xf8, 0x18, 0x5b,
0x71, 0xec, 0x3d, 0x16, 0xcb, 0xdf, 0x3e, 0x20, 0xd6, 0x61, 0x62, 0x96, 0x8b, 0xd0, 0x53, 0x4a,
0xa9, 0xb5, 0xcd, 0x19, 0x5d, 0x09, 0xb8, 0x6f, 0xeb, 0x3f, 0x84, 0x0b, 0x15, 0x84, 0xca, 0x3c,
0xaf, 0xc3, 0xdc, 0x53, 0x1c, 0xee, 0xe1, 0xa7, 0xc4, 0x0c, 0x31, 0x73, 0xa8, 0xa0, 0x6e, 0x19,
0x03, 0x05, 0x34, 0x38, 0x4c, 0x7f, 0x02, 0x5a, 0x8e, 0x03, 0xf5, 0x02, 0x6c, 0xb1, 0x26, 0xc2,
0xd1, 0x3a, 0xf4, 0x83, 0x90, 0x60, 0xd7, 0xa5, 0x16, 0x66, 0x44, 0xd8, 0xa7, 0x6d, 0x64, 0x41,
0xfa, 0x2a, 0x5c, 0xac, 0x64, 0x2e, 0x17, 0xa8, 0x7f, 0x50, 0x58, 0x3d, 0xf5, 0x3c, 0xa7, 0x91,
0x68, 0xfd, 0x52, 0x69, 0xd5, 0x82, 0x52, 0xf1, 0xfd, 0x6e, 0x61, 0xd6, 0x25, 0xd8, 0x8f, 0x83,
0x46, 0x8c, 0x8b, 0x2b, 0x4e, 0x48, 0x53, 0xce, 0x2b, 0xd2, 0x6d, 0xb6, 0xa9, 0xeb, 0x12, 0x8b,
0x39, 0xd4, 0x4f, 0xd8, 0xae, 0x01, 0x58, 0x29, 0x50, 0x39, 0x51, 0x06, 0xa2, 0x6b, 0x30, 0x2c,
0x93, 0x2a, 0xb6, 0xff, 0x68, 0xc1, 0xf9, 0x5b, 0xca, 0x68, 0x52, 0x70, 0xa3, 0x0d, 0xc8, 0x8b,
0x3c, 0x53, 0x14, 0x59, 0xdc, 0xa0, 0x76, 0x69, 0x83, 0x38, 0x46, 0x48, 0x02, 0xd7, 0xb1, 0xb0,
0x60, 0xd1, 0x11, 0x2c, 0xb2, 0x20, 0xb4, 0x00, 0x6d, 0xc6, 0x5c, 0xe1, 0xb9, 0x3d, 0x83, 0x0f,
0xd1, 0x16, 0x2c, 0x7b, 0xc4, 0xa3, 0xe1, 0xc8, 0xf4, 0x70, 0x60, 0x7a, 0xf8, 0xd8, 0xe4, 0x6e,
0x6e, 0x7a, 0x7b, 0xc3, 0x19, 0xb1, 0x3e, 0x24, 0x67, 0x1f, 0xe0, 0xe0, 0x01, 0x3e, 0xde, 0x75,
0x5e, 0x90, 0x07, 0x7b, 0xfa, 0x10, 0x96, 0x8b, 0xfa, 0x29, 0xd5, 0xbf, 0x03, 0x2b, 0x12, 0xb2,
0x3b, 0xf2, 0xad, 0x5d, 0x11, 0x5b, 0x8d, 0x36, 0xea, 0xbf, 0x2d, 0x18, 0x96, 0x09, 0x95, 0xe7,
0xbf, 0xac, 0xd5, 0x4e, 0x6d, 0x93, 0xcb, 0xd0, 0x67, 0xd8, 0x71, 0x4d, 0xba, 0xbf, 0x1f, 0x11,
0x26, 0x0c, 0xd1, 0x31, 0x80, 0x83, 0x1e, 0x0a, 0x08, 0xba, 0x0a, 0x0b, 0x96, 0xf4, 0x7e, 0x33,
0x24, 0x47, 0x8e, 0xc8, 0x06, 0xb3, 0x62, 0x61, 0xf3, 0x56, 0x12, 0x15, 0x12, 0x8c, 0x74, 0x98,
0x73, 0xec, 0x63, 0x53, 0xa4, 0x23, 0x91, 0x4c, 0xba, 0x82, 0x5b, 0xdf, 0xb1, 0x8f, 0xef, 0x39,
0x2e, 0xe1, 0x16, 0xd5, 0x1f, 0xc3, 0x25, 0xa9, 0xfc, 0x7d, 0xdf, 0x0a, 0x89, 0x47, 0x7c, 0x86,
0xdd, 0x6d, 0x1a, 0x8c, 0x1a, 0xb9, 0xcd, 0x05, 0xe8, 0x46, 0x8e, 0x6f, 0x11, 0xd3, 0x97, 0x49,
0xad, 0x63, 0xcc, 0x8a, 0xef, 0x9d, 0x48, 0xbf, 0x0d, 0xab, 0x35, 0x7c, 0x95, 0x65, 0x5f, 0x83,
0x81, 0x58, 0x98, 0x45, 0x7d, 0x46, 0x7c, 0x26, 0x78, 0x0f, 0x8c, 0x3e, 0x87, 0x6d, 0x4b, 0x90,
0xfe, 0x2e, 0x20, 0xc9, 0xe3, 0x01, 0x8d, 0xfd, 0x66, 0xe1, 0x7c, 0x1e, 0x16, 0x73, 0x24, 0xca,
0x37, 0xde, 0x83, 0x25, 0x09, 0xfe, 0xdc, 0xf7, 0x1a, 0xf3, 0x5a, 0x81, 0xf3, 0x05, 0x22, 0xc5,
0x6d, 0x2b, 0x11, 0x92, 0x3f, 0x76, 0x4e, 0x64, 0xb6, 0x9c, 0xac, 0x20, 0x7f, 0xf2, 0x88, 0xcc,
0x25, 0x17, 0x8c, 0xc3, 0x43, 0x83, 0x60, 0x9b, 0xfa, 0xee, 0xa8, 0x71, 0xe6, 0xaa, 0xa0, 0x54,
0x7c, 0xff, 0xd4, 0x82, 0x73, 0x49, 0x4a, 0x6b, 0xb8, 0x9b, 0xa7, 0x74, 0xe7, 0x76, 0xad, 0x3b,
0x77, 0xc6, 0xee, 0xbc, 0x01, 0x0b, 0x11, 0x8d, 0x43, 0x8b, 0x98, 0x36, 0x66, 0xd8, 0xf4, 0xa9,
0x4d, 0x94, 0xb7, 0x9f, 0x95, 0xf0, 0x3b, 0x98, 0xe1, 0x1d, 0x6a, 0x13, 0xfd, 0x07, 0xc9, 0x66,
0xe7, 0xbc, 0xe4, 0x2a, 0x9c, 0x73, 0x71, 0xc4, 0x4c, 0x1c, 0x04, 0xc4, 0xb7, 0x4d, 0xcc, 0xb8,
0xab, 0xb5, 0x84, 0xab, 0x9d, 0xe5, 0x13, 0xb7, 0x04, 0xfc, 0x16, 0xdb, 0x89, 0xf4, 0xbf, 0xb5,
0x60, 0x9e, 0xd3, 0x72, 0xd7, 0x6e, 0xa4, 0xef, 0x02, 0xb4, 0xc9, 0x31, 0x53, 0x8a, 0xf2, 0x21,
0xba, 0x01, 0x8b, 0x2a, 0x86, 0x1c, 0xea, 0x8f, 0xc3, 0xab, 0x2d, 0xb3, 0xd1, 0x78, 0x2a, 0x8d,
0xb0, 0xcb, 0xd0, 0x8f, 0x18, 0x0d, 0x92, 0x68, 0xed, 0xc8, 0x68, 0xe5, 0x20, 0x15, 0xad, 0x79,
0x9b, 0x4e, 0x57, 0xd8, 0x74, 0xe0, 0x44, 0x26, 0xb1, 0x4c, 0xb9, 0x2a, 0x11, 0xef, 0x5d, 0x03,
0x9c, 0xe8, 0xae, 0x25, 0xad, 0xa1, 0x7f, 0x1b, 0x16, 0xc6, 0x5a, 0x35, 0x8f, 0x9d, 0xaf, 0x5a,
0x49, 0x3a, 0x7c, 0x84, 0x1d, 0x77, 0x97, 0xf8, 0x36, 0x09, 0x5f, 0x32, 0xa6, 0xd1, 0x4d, 0x58,
0x72, 0x6c, 0x97, 0x98, 0xcc, 0xf1, 0x08, 0x8d, 0x99, 0x19, 0x11, 0x8b, 0xfa, 0x76, 0x94, 0xd8,
0x87, 0xcf, 0x3d, 0x92, 0x53, 0xbb, 0x72, 0x46, 0xff, 0x6d, 0x9a, 0x5b, 0xb3, 0xab, 0x18, 0x57,
0x15, 0x3e, 0x21, 0x9c, 0xe1, 0x01, 0xc1, 0x36, 0x09, 0x95, 0x1a, 0x03, 0x09, 0xfc, 0xb1, 0x80,
0x71, 0x0b, 0x2b, 0xa4, 0x3d, 0x6a, 0x8f, 0xc4, 0x8a, 0x06, 0x06, 0x48, 0xd0, 0x6d, 0x6a, 0x8f,
0x44, 0x92, 0x8b, 0x4c, 0xe1, 0x24, 0xd6, 0x41, 0xec, 0x1f, 0x8a, 0xd5, 0x74, 0x8d, 0xbe, 0x13,
0x7d, 0x8a, 0x23, 0xb6, 0xcd, 0x41, 0xfa, 0x9f, 0x5b, 0x49, 0x94, 0xf1, 0x65, 0x18, 0xc4, 0x22,
0xce, 0xd1, 0xff, 0xc1, 0x1c, 0x9c, 0x42, 0x45, 0x43, 0xae, 0xba, 0x54, 0x01, 0x83, 0xe4, 0x9c,
0x3a, 0x8b, 0xc4, 0xcc, 0x38, 0xc8, 0xf3, 0x0b, 0x57, 0x41, 0xfe, 0x65, 0x92, 0x64, 0xef, 0x5a,
0xbb, 0x07, 0x38, 0xb4, 0xa3, 0x1f, 0x11, 0x9f, 0x84, 0x98, 0xbd, 0x92, 0x43, 0x5f, 0x5f, 0x87,
0xb5, 0x3a, 0xee, 0x4a, 0xfe, 0x93, 0xe4, 0xf0, 0x48, 0x30, 0x0c, 0xb2, 0x17, 0x3b, 0xae, 0xfd,
0x4a, 0xc4, 0x7f, 0x52, 0x54, 0x2e, 0x65, 0xae, 0xfc, 0xe7, 0x1a, 0x9c, 0x0b, 0x05, 0x88, 0x99,
0x11, 0x47, 0x48, 0xeb, 0xfd, 0x39, 0x63, 0x5e, 0x4d, 0x08, 0x42, 0x5e, 0xf7, 0xff, 0x25, 0xf5,
0x80, 0x84, 0xdb, 0x2b, 0x4b, 0x8b, 0x17, 0xa1, 0x37, 0x16, 0xdf, 0x16, 0xe2, 0xbb, 0x91, 0x92,
0xcb, 0xbd, 0xd3, 0xa2, 0xc1, 0xc8, 0x24, 0x96, 0x3c, 0x87, 0xc5, 0x56, 0x77, 0x8d, 0x3e, 0x07,
0xde, 0xb5, 0xc4, 0x31, 0x7c, 0x8a, 0x1c, 0x99, 0x7a, 0x43, 0x5e, 0x09, 0xb5, 0x1b, 0xcf, 0xe1,
0x62, 0x7e, 0xb6, 0xf9, 0xf1, 0xf4, 0x52, 0x4a, 0xea, 0x6b, 0x45, 0x37, 0x28, 0x9c, 0x71, 0x47,
0xc5, 0x65, 0x37, 0x3e, 0xcf, 0x5f, 0x6e, 0x5d, 0xab, 0x45, 0x83, 0xe4, 0x8b, 0x82, 0x2f, 0x8a,
0xcb, 0x3e, 0x45, 0x71, 0x70, 0xb2, 0xe0, 0xcb, 0x45, 0xd7, 0x2d, 0x56, 0x10, 0xbf, 0x4f, 0xf3,
0xa2, 0xc2, 0xe0, 0xe7, 0x77, 0xe3, 0x7c, 0xa4, 0xe4, 0x0a, 0x73, 0xcc, 0x19, 0xb3, 0x4a, 0x2c,
0xbf, 0x60, 0xaa, 0x73, 0x48, 0xd6, 0xe7, 0xea, 0x2b, 0x77, 0x95, 0x6c, 0xab, 0xab, 0x64, 0x72,
0x45, 0x3e, 0x24, 0x23, 0xe1, 0x6b, 0x1d, 0x79, 0x45, 0xfe, 0x84, 0x8c, 0xf4, 0x9d, 0x42, 0xa4,
0xc8, 0xa5, 0xa9, 0x98, 0x43, 0xd0, 0xe1, 0x4e, 0xaa, 0x52, 0xb5, 0x18, 0xa3, 0x55, 0x00, 0x27,
0x32, 0x6d, 0xb1, 0xe7, 0x72, 0x51, 0x5d, 0xa3, 0xe7, 0x28, 0x27, 0xb0, 0xf5, 0xdf, 0x65, 0x42,
0xef, 0xb6, 0x4b, 0xf7, 0x5e, 0xa1, 0x57, 0x66, 0xb5, 0x68, 0xe7, 0xb4, 0xc8, 0xde, 0x95, 0x3b,
0xf9, 0xbb, 0x72, 0x26, 0x88, 0xb2, 0xcb, 0x51, 0x3b, 0xf3, 0x21, 0x5c, 0xe4, 0x0a, 0x4b, 0x0c,
0x51, 0x25, 0x37, 0xbf, 0x49, 0xfc, 0xeb, 0x0c, 0x5c, 0xaa, 0x26, 0x6e, 0x72, 0x9b, 0xf8, 0x08,
0xb4, 0xb4, 0x5a, 0xe7, 0x47, 0x4a, 0xc4, 0xb0, 0x17, 0xa4, 0x87, 0x8a, 0x3c, 0x7b, 0x56, 0x54,
0xe9, 0xfe, 0x28, 0x99, 0x4f, 0x4e, 0x96, 0x52, 0xa9, 0xdf, 0x2e, 0x95, 0xfa, 0x5c, 0x80, 0x8d,
0x59, 0x9d, 0x00, 0x59, 0xbb, 0xac, 0xd8, 0x98, 0xd5, 0x09, 0x48, 0x89, 0x85, 0x00, 0xe9, 0x35,
0x7d, 0x85, 0x2f, 0x04, 0xac, 0x02, 0xa8, 0xb2, 0x24, 0xf6, 0x93, 0xab, 0x4b, 0x4f, 0x16, 0x25,
0xb1, 0x5f, 0x5b, 0x5d, 0xcd, 0xd6, 0x56, 0x57, 0xf9, 0xed, 0xef, 0x96, 0x4e, 0x88, 0x2f, 0x00,
0xee, 0x38, 0xd1, 0xa1, 0x34, 0x32, 0x2f, 0xe7, 0x6c, 0x27, 0x54, 0xf7, 0x65, 0x3e, 0xe4, 0x10,
0xec, 0xba, 0xca, 0x74, 0x7c, 0xc8, 0xdd, 0x37, 0x8e, 0x88, 0xad, 0xac, 0x23, 0xc6, 0x1c, 0xb6,
0x1f, 0x12, 0xa2, 0x0c, 0x20, 0xc6, 0xfa, 0x1f, 0x5a, 0xd0, 0x7b, 0x40, 0x3c, 0xc5, 0x79, 0x0d,
0xe0, 0x29, 0x0d, 0x69, 0xcc, 0x1c, 0x9f, 0xc8, 0xea, 0x73, 0xda, 0xc8, 0x40, 0xbe, 0xbe, 0x1c,
0x11, 0x9a, 0xc4, 0xdd, 0x57, 0xc6, 0x14, 0x63, 0x0e, 0x3b, 0x20, 0x38, 0x50, 0xf6, 0x13, 0x63,
0xb4, 0x04, 0xd3, 0x11, 0xc3, 0xd6, 0xa1, 0x30, 0x56, 0xc7, 0x90, 0x1f, 0xfa, 0x7f, 0x06, 0x30,
0xf8, 0x2c, 0x26, 0xe1, 0x28, 0xd3, 0x39, 0x88, 0x88, 0xb2, 0x4e, 0xd2, 0xfa, 0xca, 0x40, 0xf8,
0x26, 0xee, 0x87, 0xd4, 0x33, 0xd3, 0xee, 0xd8, 0x19, 0x81, 0xd2, 0xe7, 0xc0, 0x7b, 0xb2, 0x43,
0x86, 0x3e, 0x86, 0x99, 0x7d, 0xc7, 0x65, 0x44, 0xf6, 0xa3, 0xfa, 0x5b, 0x6f, 0x96, 0x3b, 0x61,
0x59, 0x99, 0x9b, 0xf7, 0x04, 0xb2, 0xa1, 0x88, 0xd0, 0x1e, 0x2c, 0x3a, 0x7e, 0x20, 0xaa, 0xa1,
0xd0, 0xc1, 0xae, 0xf3, 0x62, 0x7c, 0xf7, 0xed, 0x6f, 0xbd, 0x3b, 0x81, 0xd7, 0x7d, 0x4e, 0xb9,
0x9b, 0x25, 0x34, 0x90, 0x53, 0x82, 0x21, 0x02, 0x4b, 0x34, 0x66, 0x65, 0x21, 0xd3, 0x42, 0xc8,
0xd6, 0x04, 0x21, 0x0f, 0x05, 0x69, 0x5e, 0xca, 0x22, 0x2d, 0x03, 0xb5, 0x1d, 0x98, 0x91, 0xca,
0x71, 0xf3, 0xef, 0x3b, 0xc4, 0x4d, 0x3a, 0x7a, 0xf2, 0x83, 0xa7, 0x18, 0x1a, 0x90, 0x10, 0xfb,
0xb6, 0x4a, 0x4d, 0xc9, 0x27, 0xc7, 0x3f, 0xc2, 0x6e, 0x4c, 0x92, 0x96, 0x9e, 0xf8, 0xd0, 0xfe,
0x3e, 0x0d, 0xa8, 0xac, 0x61, 0x72, 0xa1, 0x0f, 0x49, 0xc4, 0x9d, 0xde, 0x64, 0xa3, 0x80, 0x28,
0x39, 0xf3, 0x19, 0xf8, 0xa3, 0x51, 0x40, 0xd0, 0xcf, 0xa0, 0x67, 0x45, 0x47, 0xa6, 0x30, 0x89,
0x90, 0xd9, 0xdf, 0xfa, 0xf0, 0xd4, 0x26, 0xdd, 0xdc, 0xde, 0x7d, 0x2c, 0xa0, 0x46, 0xd7, 0x8a,
0x8e, 0xc4, 0x08, 0xfd, 0x02, 0xe0, 0x57, 0x11, 0xf5, 0x15, 0x67, 0xb9, 0xf1, 0x1f, 0x9d, 0x9e,
0xf3, 0x4f, 0x76, 0x1f, 0xee, 0x48, 0xd6, 0x3d, 0xce, 0x4e, 0xf2, 0xb6, 0x60, 0x2e, 0xc0, 0xe1,
0xb3, 0x98, 0x30, 0xc5, 0x5e, 0xfa, 0xc2, 0xf7, 0x4f, 0xcf, 0xfe, 0xa7, 0x92, 0x8d, 0x94, 0x30,
0x08, 0x32, 0x5f, 0xda, 0x5f, 0xcf, 0x40, 0x37, 0xd1, 0x8b, 0x17, 0x54, 0xc2, 0xc3, 0xe5, 0xb5,
0xc2, 0x74, 0xfc, 0x7d, 0xaa, 0x2c, 0x7a, 0x96, 0xc3, 0xe5, 0xcd, 0xe2, 0xbe, 0xbf, 0x4f, 0xb9,
0xed, 0x43, 0x62, 0xd1, 0xd0, 0xe6, 0xc7, 0x97, 0xe3, 0x39, 0xdc, 0xed, 0xe5, 0x5e, 0xce, 0x4b,
0xf8, 0x9d, 0x04, 0x8c, 0xae, 0xc0, 0xbc, 0xd8, 0xf6, 0x0c, 0x66, 0x3b, 0xe1, 0x49, 0xdc, 0x0c,
0xe2, 0x55, 0x58, 0x78, 0x16, 0x53, 0x46, 0x4c, 0xeb, 0x00, 0x87, 0xd8, 0x62, 0x34, 0x2d, 0xf0,
0xe7, 0x05, 0x7c, 0x3b, 0x05, 0xa3, 0x6f, 0xc1, 0xb2, 0x44, 0x25, 0x91, 0x85, 0x83, 0x94, 0x82,
0x84, 0xaa, 0xfe, 0x5b, 0x12, 0xb3, 0x77, 0xc5, 0xe4, 0x76, 0x32, 0x87, 0x34, 0xe8, 0x5a, 0xd4,
0xf3, 0x88, 0xcf, 0x22, 0x91, 0x24, 0x7a, 0x46, 0xfa, 0x8d, 0x6e, 0xc1, 0x2a, 0x76, 0x5d, 0xfa,
0xdc, 0x14, 0x94, 0xb6, 0x59, 0xd2, 0x6e, 0x56, 0x1c, 0xcf, 0x9a, 0x40, 0xfa, 0x4c, 0xe0, 0x18,
0x79, 0x45, 0xb5, 0xcb, 0xd0, 0x4b, 0xf7, 0x91, 0x27, 0xa3, 0x8c, 0x43, 0x8a, 0xb1, 0x76, 0x16,
0x06, 0xd9, 0x9d, 0xd0, 0xfe, 0xdd, 0x86, 0xc5, 0x8a, 0xa0, 0x42, 0x4f, 0x00, 0xb8, 0xb7, 0xca,
0xd0, 0x52, 0xee, 0xfa, 0xbd, 0xd3, 0x07, 0x27, 0xf7, 0x57, 0x09, 0x36, 0xb8, 0xf7, 0xcb, 0x21,
0xfa, 0x25, 0xf4, 0x85, 0xc7, 0x2a, 0xee, 0xd2, 0x65, 0x3f, 0xfe, 0x1a, 0xdc, 0xb9, 0xae, 0x8a,
0xbd, 0x88, 0x01, 0x39, 0xd6, 0xfe, 0xd9, 0x82, 0x5e, 0x2a, 0x98, 0x5f, 0xb8, 0xe5, 0x46, 0x89,
0xbd, 0x8e, 0x94, 0x39, 0xfa, 0x02, 0x76, 0x4f, 0x80, 0xbe, 0x91, 0xae, 0xa4, 0xbd, 0x0f, 0x30,
0xd6, 0xbf, 0x52, 0x85, 0x56, 0xa5, 0x0a, 0xfa, 0x55, 0x98, 0xe3, 0x96, 0x75, 0x88, 0xbd, 0xcb,
0x42, 0x27, 0x10, 0x6f, 0x13, 0x12, 0x27, 0x52, 0xb5, 0x61, 0xf2, 0xb9, 0xf5, 0xc7, 0x15, 0x18,
0x64, 0xef, 0xb4, 0xe8, 0x4b, 0xe8, 0x67, 0xde, 0x60, 0xd0, 0x1b, 0xe5, 0x4d, 0x2b, 0xbf, 0xe9,
0x68, 0x6f, 0x4e, 0xc0, 0x52, 0xe5, 0xdb, 0x14, 0xf2, 0xe1, 0x5c, 0xe9, 0x21, 0x03, 0x5d, 0x2b,
0x53, 0xd7, 0x3d, 0x93, 0x68, 0xd7, 0x1b, 0xe1, 0xa6, 0xf2, 0x18, 0x2c, 0x56, 0xbc, 0x4c, 0xa0,
0xb7, 0x27, 0x70, 0xc9, 0xbd, 0x8e, 0x68, 0xef, 0x34, 0xc4, 0x4e, 0xa5, 0x3e, 0x03, 0x54, 0x7e,
0xb6, 0x40, 0xd7, 0x27, 0xb2, 0x19, 0x3f, 0x8b, 0x68, 0x6f, 0x37, 0x43, 0xae, 0x55, 0x54, 0x3e,
0x68, 0x4c, 0x54, 0x34, 0xf7, 0x64, 0x32, 0x51, 0xd1, 0xc2, 0x2b, 0xc9, 0x14, 0x3a, 0x84, 0x85,
0xe2, 0x63, 0x07, 0xba, 0x5a, 0xf7, 0x38, 0x57, 0x7a, 0x4b, 0xd1, 0xae, 0x35, 0x41, 0x4d, 0x85,
0x11, 0x38, 0x9b, 0x7f, 0x5c, 0x40, 0x57, 0xca, 0xf4, 0x95, 0xcf, 0x2b, 0xda, 0xc6, 0x64, 0xc4,
0xac, 0x4e, 0xc5, 0x07, 0x87, 0x2a, 0x9d, 0x6a, 0x5e, 0x33, 0xaa, 0x74, 0xaa, 0x7b, 0xbf, 0xd0,
0xa7, 0xd0, 0xaf, 0x93, 0x2e, 0x76, 0xa1, 0x11, 0x8f, 0x36, 0xeb, 0xd8, 0x54, 0xbf, 0x04, 0x68,
0x37, 0x1a, 0xe3, 0x27, 0xb2, 0x6f, 0xb6, 0x78, 0xac, 0x67, 0xfa, 0xf1, 0x55, 0xb1, 0x5e, 0xee,
0xf0, 0x57, 0xc5, 0x7a, 0x55, 0x53, 0x7f, 0x0a, 0xed, 0xc1, 0x5c, 0xae, 0x43, 0x8f, 0xde, 0xaa,
0xa3, 0xcc, 0x5f, 0xed, 0xb5, 0x2b, 0x13, 0xf1, 0x52, 0x19, 0x66, 0x92, 0xbd, 0x54, 0xba, 0xaa,
0x5d, 0x5c, 0x3e, 0x5f, 0xbd, 0x35, 0x09, 0x2d, 0x17, 0xca, 0xa5, 0x3e, 0x7e, 0x65, 0x28, 0xd7,
0xbd, 0x13, 0x54, 0x86, 0x72, 0xfd, 0xd3, 0xc0, 0x14, 0xfa, 0x39, 0xc0, 0xb8, 0xd7, 0x8e, 0x5e,
0xaf, 0xa3, 0xce, 0xee, 0xfe, 0x1b, 0x27, 0x23, 0xa5, 0xac, 0x9f, 0xc3, 0x52, 0xd5, 0x15, 0x18,
0x55, 0x04, 0xfe, 0x09, 0xf7, 0x6c, 0x6d, 0xb3, 0x29, 0x7a, 0x2a, 0xf8, 0x73, 0xe8, 0x26, 0x7d,
0x72, 0xf4, 0x5a, 0x99, 0xba, 0xf0, 0x32, 0xa0, 0xe9, 0x27, 0xa1, 0x64, 0x1c, 0xd8, 0x4b, 0x62,
0x75, 0xdc, 0xc0, 0xae, 0x8f, 0xd5, 0x52, 0xab, 0xbd, 0x3e, 0x56, 0xcb, 0xfd, 0x70, 0x21, 0x2e,
0x75, 0x86, 0x6c, 0xbf, 0xb7, 0xde, 0x19, 0x2a, 0xda, 0xd9, 0xf5, 0xce, 0x50, 0xd9, 0x42, 0x9e,
0x42, 0xbf, 0x81, 0xe5, 0xea, 0x36, 0x2f, 0xaa, 0x8d, 0xf8, 0x9a, 0x76, 0xb3, 0x76, 0xb3, 0x39,
0x41, 0x2a, 0xfe, 0x45, 0x92, 0x9f, 0x0a, 0x6d, 0xde, 0xfa, 0xfc, 0x54, 0xdd, 0x6c, 0xd6, 0x6e,
0x34, 0xc6, 0x2f, 0x87, 0x5e, 0xb6, 0x9f, 0x5a, 0x6f, 0xed, 0x8a, 0xd6, 0x71, 0xbd, 0xb5, 0x2b,
0x5b, 0xb4, 0x22, 0x3e, 0xaa, 0x7a, 0xa5, 0x55, 0xf1, 0x71, 0x42, 0x33, 0x57, 0xdb, 0x6c, 0x8a,
0x9e, 0x3b, 0xbe, 0xcb, 0xcd, 0x50, 0x34, 0x71, 0xfd, 0xb9, 0xcc, 0xfc, 0x4e, 0x43, 0xec, 0xfa,
0xdd, 0x4d, 0x32, 0xf5, 0x44, 0x05, 0x0a, 0x19, 0xfb, 0x46, 0x63, 0xfc, 0x54, 0x76, 0x90, 0xbc,
0x80, 0x66, 0x1a, 0x99, 0xe8, 0xda, 0x04, 0x3e, 0x99, 0x46, 0xac, 0x76, 0xbd, 0x11, 0x6e, 0x55,
0xf4, 0x66, 0x5b, 0x8b, 0x27, 0xf9, 0x53, 0xa9, 0x1f, 0x7a, 0x92, 0x3f, 0x55, 0x74, 0x2b, 0xa7,
0xd0, 0xa7, 0x30, 0x2d, 0xae, 0x38, 0x68, 0xed, 0xe4, 0xbb, 0x8f, 0x76, 0xb9, 0x7a, 0x3e, 0xad,
0xe0, 0xb9, 0x02, 0x7b, 0x33, 0xe2, 0x47, 0xab, 0xf7, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0x02,
0xd4, 0xce, 0xae, 0x7f, 0x25, 0x00, 0x00,
0x51, 0xeb, 0xd5, 0xc7, 0x6e, 0xed, 0xca, 0x92, 0x5b, 0x8a, 0xb4, 0x19, 0x47, 0xb2, 0x3c, 0x4e,
0x62, 0xd9, 0x4e, 0x64, 0x47, 0x06, 0x12, 0x12, 0x02, 0xd8, 0xb2, 0x0d, 0x26, 0xb1, 0x4c, 0x46,
0x8a, 0x09, 0x38, 0x8f, 0x79, 0xbd, 0x33, 0x2d, 0x6b, 0xd0, 0xcc, 0xf4, 0x78, 0xa6, 0x47, 0xf6,
0xfa, 0xc1, 0x29, 0x3c, 0x6e, 0xfc, 0x00, 0xce, 0xdc, 0x39, 0x70, 0xe1, 0x07, 0x70, 0xe1, 0x07,
0xc0, 0x95, 0x0b, 0x67, 0x0e, 0xdc, 0x78, 0x8f, 0x0b, 0xaf, 0x3f, 0x66, 0x76, 0x3e, 0xb5, 0xa3,
0xd8, 0xef, 0xf1, 0xb8, 0xcd, 0x56, 0xd7, 0x47, 0x57, 0x75, 0x55, 0x75, 0x75, 0xd5, 0xc2, 0xd2,
0x31, 0x75, 0x63, 0x8f, 0x98, 0x11, 0x09, 0x8f, 0x49, 0xb8, 0x15, 0x84, 0x94, 0x51, 0xb4, 0x98,
0x03, 0x9a, 0xc1, 0x50, 0xbf, 0x0e, 0xe8, 0x36, 0x66, 0xd6, 0xe1, 0x1d, 0xe2, 0x12, 0x46, 0x0c,
0xf2, 0x34, 0x26, 0x11, 0x43, 0xaf, 0x43, 0xe7, 0xc0, 0x71, 0x89, 0xe9, 0xd8, 0xd1, 0xa0, 0xb5,
0xd1, 0xde, 0xec, 0x1a, 0x73, 0xfc, 0xf7, 0x7d, 0x3b, 0xd2, 0x1f, 0xc2, 0x52, 0x8e, 0x20, 0x0a,
0xa8, 0x1f, 0x11, 0xf4, 0x01, 0xcc, 0x85, 0x24, 0x8a, 0x5d, 0x26, 0x09, 0x7a, 0xdb, 0xeb, 0x5b,
0x45, 0x59, 0x5b, 0x29, 0x49, 0xec, 0x32, 0x23, 0x41, 0xd7, 0xbf, 0x6a, 0x41, 0x3f, 0xbb, 0x82,
0x56, 0x61, 0x4e, 0x09, 0x1f, 0xb4, 0x36, 0x5a, 0x9b, 0x5d, 0x63, 0x56, 0xca, 0x46, 0x2b, 0x30,
0x1b, 0x31, 0xcc, 0xe2, 0x68, 0x70, 0x66, 0xa3, 0xb5, 0x39, 0x63, 0xa8, 0x5f, 0x68, 0x19, 0x66,
0x48, 0x18, 0xd2, 0x70, 0xd0, 0x16, 0xe8, 0xf2, 0x07, 0x42, 0x30, 0x1d, 0x39, 0x2f, 0xc8, 0x60,
0x7a, 0xa3, 0xb5, 0x39, 0x6f, 0x88, 0x6f, 0x34, 0x80, 0xb9, 0x63, 0x12, 0x46, 0x0e, 0xf5, 0x07,
0x33, 0x02, 0x9c, 0xfc, 0xd4, 0xe7, 0x60, 0xe6, 0xae, 0x17, 0xb0, 0x91, 0xfe, 0x3e, 0x0c, 0x1e,
0x61, 0x2b, 0x8e, 0xbd, 0x47, 0x62, 0xfb, 0x3b, 0x87, 0xc4, 0x3a, 0x4a, 0xcc, 0x72, 0x1e, 0xba,
0x4a, 0x29, 0xb5, 0xb7, 0x79, 0xa3, 0x23, 0x01, 0xf7, 0x6d, 0xfd, 0xfb, 0xf0, 0x7a, 0x05, 0xa1,
0x32, 0xcf, 0x25, 0x98, 0x7f, 0x82, 0xc3, 0x21, 0x7e, 0x42, 0xcc, 0x10, 0x33, 0x87, 0x0a, 0xea,
0x96, 0xd1, 0x57, 0x40, 0x83, 0xc3, 0xf4, 0xc7, 0xa0, 0xe5, 0x38, 0x50, 0x2f, 0xc0, 0x16, 0x6b,
0x22, 0x1c, 0x6d, 0x40, 0x2f, 0x08, 0x09, 0x76, 0x5d, 0x6a, 0x61, 0x46, 0x84, 0x7d, 0xda, 0x46,
0x16, 0xa4, 0xaf, 0xc1, 0xf9, 0x4a, 0xe6, 0x72, 0x83, 0xfa, 0x07, 0x85, 0xdd, 0x53, 0xcf, 0x73,
0x1a, 0x89, 0xd6, 0xdf, 0x28, 0xed, 0x5a, 0x50, 0x2a, 0xbe, 0xdf, 0x2e, 0xac, 0xba, 0x04, 0xfb,
0x71, 0xd0, 0x88, 0x71, 0x71, 0xc7, 0x09, 0x69, 0xca, 0x79, 0x55, 0xba, 0xcd, 0x0e, 0x75, 0x5d,
0x62, 0x31, 0x87, 0xfa, 0x09, 0xdb, 0x75, 0x00, 0x2b, 0x05, 0x2a, 0x27, 0xca, 0x40, 0x74, 0x0d,
0x06, 0x65, 0x52, 0xc5, 0xf6, 0xef, 0x2d, 0x78, 0xed, 0x96, 0x32, 0x9a, 0x14, 0xdc, 0xe8, 0x00,
0xf2, 0x22, 0xcf, 0x14, 0x45, 0x16, 0x0f, 0xa8, 0x5d, 0x3a, 0x20, 0x8e, 0x11, 0x92, 0xc0, 0x75,
0x2c, 0x2c, 0x58, 0x4c, 0x0b, 0x16, 0x59, 0x10, 0x5a, 0x84, 0x36, 0x63, 0xae, 0xf0, 0xdc, 0xae,
0xc1, 0x3f, 0xd1, 0x36, 0xac, 0x78, 0xc4, 0xa3, 0xe1, 0xc8, 0xf4, 0x70, 0x60, 0x7a, 0xf8, 0xb9,
0xc9, 0xdd, 0xdc, 0xf4, 0x86, 0x83, 0x59, 0xb1, 0x3f, 0x24, 0x57, 0x1f, 0xe0, 0xe0, 0x01, 0x7e,
0xbe, 0xe7, 0xbc, 0x20, 0x0f, 0x86, 0xfa, 0x00, 0x56, 0x8a, 0xfa, 0x29, 0xd5, 0xbf, 0x05, 0xab,
0x12, 0xb2, 0x37, 0xf2, 0xad, 0x3d, 0x11, 0x5b, 0x8d, 0x0e, 0xea, 0x3f, 0x2d, 0x18, 0x94, 0x09,
0x95, 0xe7, 0xbf, 0xac, 0xd5, 0x4e, 0x6d, 0x93, 0x0b, 0xd0, 0x63, 0xd8, 0x71, 0x4d, 0x7a, 0x70,
0x10, 0x11, 0x26, 0x0c, 0x31, 0x6d, 0x00, 0x07, 0x3d, 0x14, 0x10, 0x74, 0x05, 0x16, 0x2d, 0xe9,
0xfd, 0x66, 0x48, 0x8e, 0x1d, 0x91, 0x0d, 0xe6, 0xc4, 0xc6, 0x16, 0xac, 0x24, 0x2a, 0x24, 0x18,
0xe9, 0x30, 0xef, 0xd8, 0xcf, 0x4d, 0x91, 0x8e, 0x44, 0x32, 0xe9, 0x08, 0x6e, 0x3d, 0xc7, 0x7e,
0x7e, 0xcf, 0x71, 0x09, 0xb7, 0xa8, 0xfe, 0x08, 0xde, 0x90, 0xca, 0xdf, 0xf7, 0xad, 0x90, 0x78,
0xc4, 0x67, 0xd8, 0xdd, 0xa1, 0xc1, 0xa8, 0x91, 0xdb, 0xbc, 0x0e, 0x9d, 0xc8, 0xf1, 0x2d, 0x62,
0xfa, 0x32, 0xa9, 0x4d, 0x1b, 0x73, 0xe2, 0xf7, 0x6e, 0xa4, 0xdf, 0x86, 0xb5, 0x1a, 0xbe, 0xca,
0xb2, 0x17, 0xa1, 0x2f, 0x36, 0x66, 0x51, 0x9f, 0x11, 0x9f, 0x09, 0xde, 0x7d, 0xa3, 0xc7, 0x61,
0x3b, 0x12, 0xa4, 0xbf, 0x07, 0x48, 0xf2, 0x78, 0x40, 0x63, 0xbf, 0x59, 0x38, 0xbf, 0x06, 0x4b,
0x39, 0x12, 0xe5, 0x1b, 0x37, 0x61, 0x59, 0x82, 0x3f, 0xf7, 0xbd, 0xc6, 0xbc, 0x56, 0xe1, 0xb5,
0x02, 0x91, 0xe2, 0xb6, 0x9d, 0x08, 0xc9, 0x5f, 0x3b, 0x27, 0x32, 0x5b, 0x49, 0x76, 0x90, 0xbf,
0x79, 0x44, 0xe6, 0x92, 0x1b, 0xc6, 0xe1, 0x91, 0x41, 0xb0, 0x4d, 0x7d, 0x77, 0xd4, 0x38, 0x73,
0x55, 0x50, 0x2a, 0xbe, 0x7f, 0x68, 0xc1, 0xb9, 0x24, 0xa5, 0x35, 0x3c, 0xcd, 0x53, 0xba, 0x73,
0xbb, 0xd6, 0x9d, 0xa7, 0xc7, 0xee, 0xbc, 0x09, 0x8b, 0x11, 0x8d, 0x43, 0x8b, 0x98, 0x36, 0x66,
0xd8, 0xf4, 0xa9, 0x4d, 0x94, 0xb7, 0x9f, 0x95, 0xf0, 0x3b, 0x98, 0xe1, 0x5d, 0x6a, 0x13, 0xfd,
0x7b, 0xc9, 0x61, 0xe7, 0xbc, 0xe4, 0x0a, 0x9c, 0x73, 0x71, 0xc4, 0x4c, 0x1c, 0x04, 0xc4, 0xb7,
0x4d, 0xcc, 0xb8, 0xab, 0xb5, 0x84, 0xab, 0x9d, 0xe5, 0x0b, 0xb7, 0x04, 0xfc, 0x16, 0xdb, 0x8d,
0xf4, 0xbf, 0xb6, 0x60, 0x81, 0xd3, 0x72, 0xd7, 0x6e, 0xa4, 0xef, 0x22, 0xb4, 0xc9, 0x73, 0xa6,
0x14, 0xe5, 0x9f, 0xe8, 0x3a, 0x2c, 0xa9, 0x18, 0x72, 0xa8, 0x3f, 0x0e, 0xaf, 0xb6, 0xcc, 0x46,
0xe3, 0xa5, 0x34, 0xc2, 0x2e, 0x40, 0x2f, 0x62, 0x34, 0x48, 0xa2, 0x75, 0x5a, 0x46, 0x2b, 0x07,
0xa9, 0x68, 0xcd, 0xdb, 0x74, 0xa6, 0xc2, 0xa6, 0x7d, 0x27, 0x32, 0x89, 0x65, 0xca, 0x5d, 0x89,
0x78, 0xef, 0x18, 0xe0, 0x44, 0x77, 0x2d, 0x69, 0x0d, 0xfd, 0x9b, 0xb0, 0x38, 0xd6, 0xaa, 0x79,
0xec, 0x7c, 0xd5, 0x4a, 0xd2, 0xe1, 0x3e, 0x76, 0xdc, 0x3d, 0xe2, 0xdb, 0x24, 0x7c, 0xc9, 0x98,
0x46, 0x37, 0x60, 0xd9, 0xb1, 0x5d, 0x62, 0x32, 0xc7, 0x23, 0x34, 0x66, 0x66, 0x44, 0x2c, 0xea,
0xdb, 0x51, 0x62, 0x1f, 0xbe, 0xb6, 0x2f, 0x97, 0xf6, 0xe4, 0x8a, 0xfe, 0xeb, 0x34, 0xb7, 0x66,
0x77, 0x31, 0xae, 0x2a, 0x7c, 0x42, 0x38, 0xc3, 0x43, 0x82, 0x6d, 0x12, 0x2a, 0x35, 0xfa, 0x12,
0xf8, 0x43, 0x01, 0xe3, 0x16, 0x56, 0x48, 0x43, 0x6a, 0x8f, 0xc4, 0x8e, 0xfa, 0x06, 0x48, 0xd0,
0x6d, 0x6a, 0x8f, 0x44, 0x92, 0x8b, 0x4c, 0xe1, 0x24, 0xd6, 0x61, 0xec, 0x1f, 0x89, 0xdd, 0x74,
0x8c, 0x9e, 0x13, 0x7d, 0x8a, 0x23, 0xb6, 0xc3, 0x41, 0xfa, 0x9f, 0x5a, 0x49, 0x94, 0xf1, 0x6d,
0x18, 0xc4, 0x22, 0xce, 0xf1, 0xff, 0xc0, 0x1c, 0x9c, 0x42, 0x45, 0x43, 0xae, 0xba, 0x54, 0x01,
0x83, 0xe4, 0x9a, 0xba, 0x8b, 0xc4, 0xca, 0x38, 0xc8, 0xf3, 0x1b, 0x57, 0x41, 0xfe, 0x65, 0x92,
0x64, 0xef, 0x5a, 0x7b, 0x87, 0x38, 0xb4, 0xa3, 0x1f, 0x10, 0x9f, 0x84, 0x98, 0xbd, 0x92, 0x4b,
0x5f, 0xdf, 0x80, 0xf5, 0x3a, 0xee, 0x4a, 0xfe, 0xe3, 0xe4, 0xf2, 0x48, 0x30, 0x0c, 0x32, 0x8c,
0x1d, 0xd7, 0x7e, 0x25, 0xe2, 0x3f, 0x29, 0x2a, 0x97, 0x32, 0x57, 0xfe, 0x73, 0x15, 0xce, 0x85,
0x02, 0xc4, 0xcc, 0x88, 0x23, 0xa4, 0xf5, 0xfe, 0xbc, 0xb1, 0xa0, 0x16, 0x04, 0x21, 0xaf, 0xfb,
0xff, 0x9c, 0x7a, 0x40, 0xc2, 0xed, 0x95, 0xa5, 0xc5, 0xf3, 0xd0, 0x1d, 0x8b, 0x6f, 0x0b, 0xf1,
0x9d, 0x48, 0xc9, 0xe5, 0xde, 0x69, 0xd1, 0x60, 0x64, 0x12, 0x4b, 0xde, 0xc3, 0xe2, 0xa8, 0x3b,
0x46, 0x8f, 0x03, 0xef, 0x5a, 0xe2, 0x1a, 0x3e, 0x45, 0x8e, 0x4c, 0xbd, 0x21, 0xaf, 0x84, 0x3a,
0x8d, 0x67, 0x70, 0x3e, 0xbf, 0xda, 0xfc, 0x7a, 0x7a, 0x29, 0x25, 0xf5, 0xf5, 0xa2, 0x1b, 0x14,
0xee, 0xb8, 0xe3, 0xe2, 0xb6, 0x1b, 0xdf, 0xe7, 0x2f, 0xb7, 0xaf, 0xb5, 0xa2, 0x41, 0xf2, 0x45,
0xc1, 0x17, 0xc5, 0x6d, 0x9f, 0xa2, 0x38, 0x38, 0x59, 0xf0, 0x85, 0xa2, 0xeb, 0x16, 0x2b, 0x88,
0xdf, 0xa5, 0x79, 0x51, 0x61, 0xf0, 0xfb, 0xbb, 0x71, 0x3e, 0x52, 0x72, 0x85, 0x39, 0xe6, 0x8d,
0x39, 0x25, 0x96, 0x3f, 0x30, 0xd5, 0x3d, 0x24, 0xeb, 0x73, 0xf5, 0x2b, 0xf7, 0x94, 0x6c, 0xab,
0xa7, 0x64, 0xf2, 0x44, 0x3e, 0x22, 0x23, 0xe1, 0x6b, 0xd3, 0xf2, 0x89, 0xfc, 0x09, 0x19, 0xe9,
0xbb, 0x85, 0x48, 0x91, 0x5b, 0x53, 0x31, 0x87, 0x60, 0x9a, 0x3b, 0xa9, 0x4a, 0xd5, 0xe2, 0x1b,
0xad, 0x01, 0x38, 0x91, 0x69, 0x8b, 0x33, 0x97, 0x9b, 0xea, 0x18, 0x5d, 0x47, 0x39, 0x81, 0xad,
0xff, 0x36, 0x13, 0x7a, 0xb7, 0x5d, 0x3a, 0x7c, 0x85, 0x5e, 0x99, 0xd5, 0xa2, 0x9d, 0xd3, 0x22,
0xfb, 0x56, 0x9e, 0xce, 0xbf, 0x95, 0x33, 0x41, 0x94, 0xdd, 0x8e, 0x3a, 0x99, 0x0f, 0xe1, 0x3c,
0x57, 0x58, 0x62, 0x88, 0x2a, 0xb9, 0xf9, 0x4b, 0xe2, 0x9f, 0x67, 0xe0, 0x8d, 0x6a, 0xe2, 0x26,
0xaf, 0x89, 0x8f, 0x40, 0x4b, 0xab, 0x75, 0x7e, 0xa5, 0x44, 0x0c, 0x7b, 0x41, 0x7a, 0xa9, 0xc8,
0xbb, 0x67, 0x55, 0x95, 0xee, 0xfb, 0xc9, 0x7a, 0x72, 0xb3, 0x94, 0x4a, 0xfd, 0x76, 0xa9, 0xd4,
0xe7, 0x02, 0x6c, 0xcc, 0xea, 0x04, 0xc8, 0xda, 0x65, 0xd5, 0xc6, 0xac, 0x4e, 0x40, 0x4a, 0x2c,
0x04, 0x48, 0xaf, 0xe9, 0x29, 0x7c, 0x21, 0x60, 0x0d, 0x40, 0x95, 0x25, 0xb1, 0x9f, 0x3c, 0x5d,
0xba, 0xb2, 0x28, 0x89, 0xfd, 0xda, 0xea, 0x6a, 0xae, 0xb6, 0xba, 0xca, 0x1f, 0x7f, 0xa7, 0x74,
0x43, 0x7c, 0x01, 0x70, 0xc7, 0x89, 0x8e, 0xa4, 0x91, 0x79, 0x39, 0x67, 0x3b, 0xa1, 0x7a, 0x2f,
0xf3, 0x4f, 0x0e, 0xc1, 0xae, 0xab, 0x4c, 0xc7, 0x3f, 0xb9, 0xfb, 0xc6, 0x11, 0xb1, 0x95, 0x75,
0xc4, 0x37, 0x87, 0x1d, 0x84, 0x84, 0x28, 0x03, 0x88, 0x6f, 0xfd, 0xf7, 0x2d, 0xe8, 0x3e, 0x20,
0x9e, 0xe2, 0xbc, 0x0e, 0xf0, 0x84, 0x86, 0x34, 0x66, 0x8e, 0x4f, 0x64, 0xf5, 0x39, 0x63, 0x64,
0x20, 0x5f, 0x5f, 0x8e, 0x08, 0x4d, 0xe2, 0x1e, 0x28, 0x63, 0x8a, 0x6f, 0x0e, 0x3b, 0x24, 0x38,
0x50, 0xf6, 0x13, 0xdf, 0x68, 0x19, 0x66, 0x22, 0x86, 0xad, 0x23, 0x61, 0xac, 0x69, 0x43, 0xfe,
0xd0, 0x7d, 0xe8, 0xef, 0x3b, 0x24, 0x24, 0xca, 0xe1, 0x78, 0x59, 0x38, 0xc4, 0xd6, 0x11, 0x2f,
0x94, 0xd9, 0x28, 0x20, 0xca, 0x14, 0x3d, 0x05, 0xdb, 0x1f, 0x05, 0x39, 0x14, 0x1f, 0x7b, 0x44,
0xc5, 0x54, 0x82, 0xb2, 0x8b, 0xbd, 0x5c, 0x97, 0x49, 0xc5, 0x54, 0x12, 0x39, 0x26, 0x6c, 0xa8,
0x62, 0xc4, 0x21, 0x21, 0xbf, 0x7a, 0xee, 0x60, 0xb6, 0x4f, 0x0d, 0xe2, 0xd1, 0x57, 0x54, 0x71,
0x5c, 0x82, 0x8b, 0x27, 0x08, 0x50, 0x11, 0xfa, 0xef, 0x3e, 0xf4, 0x3f, 0x8b, 0x49, 0x38, 0xca,
0xf4, 0x4b, 0x22, 0xa2, 0x58, 0x24, 0x0d, 0xbf, 0x0c, 0x84, 0xbb, 0xee, 0x41, 0x48, 0x3d, 0x33,
0xed, 0x09, 0x9e, 0x11, 0x28, 0x3d, 0x0e, 0xbc, 0x27, 0xfb, 0x82, 0xe8, 0x63, 0x98, 0x3d, 0x70,
0x5c, 0x46, 0x64, 0x17, 0xae, 0xb7, 0xfd, 0x56, 0xb9, 0xff, 0x97, 0x95, 0xb9, 0x75, 0x4f, 0x20,
0x1b, 0x8a, 0x08, 0x0d, 0x61, 0xc9, 0xf1, 0x03, 0x51, 0x03, 0x86, 0x0e, 0x76, 0x9d, 0x17, 0xe3,
0x17, 0x7f, 0x6f, 0xfb, 0xbd, 0x09, 0xbc, 0xee, 0x73, 0xca, 0xbd, 0x2c, 0xa1, 0x81, 0x9c, 0x12,
0x0c, 0x11, 0x58, 0xa6, 0x31, 0x2b, 0x0b, 0x99, 0x11, 0x42, 0xb6, 0x27, 0x08, 0x79, 0x28, 0x48,
0xf3, 0x52, 0x96, 0x68, 0x19, 0xa8, 0xed, 0xc2, 0xac, 0x54, 0x8e, 0x3b, 0xdd, 0x81, 0x43, 0xdc,
0xa4, 0x8f, 0x29, 0x7f, 0x70, 0xf7, 0xa0, 0x01, 0x09, 0xb1, 0x6f, 0xab, 0x03, 0x4c, 0x7e, 0x72,
0xfc, 0x63, 0xec, 0xc6, 0x24, 0x69, 0x64, 0x8a, 0x1f, 0xda, 0xdf, 0x66, 0x00, 0x95, 0x35, 0x4c,
0xda, 0x18, 0x21, 0x89, 0xb8, 0x6b, 0x65, 0xfd, 0x75, 0x21, 0x03, 0x17, 0x3e, 0xfb, 0x13, 0xe8,
0x5a, 0xd1, 0xb1, 0x29, 0x4c, 0x22, 0x64, 0xf6, 0xb6, 0x3f, 0x3c, 0xb5, 0x49, 0xb7, 0x76, 0xf6,
0x1e, 0x09, 0xa8, 0xd1, 0xb1, 0xa2, 0x63, 0xf1, 0x85, 0x7e, 0x06, 0xf0, 0x8b, 0x88, 0xfa, 0x8a,
0xb3, 0x3c, 0xf8, 0x8f, 0x4e, 0xcf, 0xf9, 0x47, 0x7b, 0x0f, 0x77, 0x25, 0xeb, 0x2e, 0x67, 0x27,
0x79, 0x5b, 0x30, 0x1f, 0xe0, 0xf0, 0x69, 0x4c, 0x98, 0x62, 0x2f, 0x7d, 0xe1, 0xbb, 0xa7, 0x67,
0xff, 0x63, 0xc9, 0x46, 0x4a, 0xe8, 0x07, 0x99, 0x5f, 0xda, 0x5f, 0xce, 0x40, 0x27, 0xd1, 0x8b,
0x97, 0x91, 0xc2, 0xc3, 0xe5, 0x63, 0xca, 0x74, 0xfc, 0x03, 0xaa, 0x2c, 0x7a, 0x96, 0xc3, 0xe5,
0x7b, 0xea, 0xbe, 0x7f, 0x40, 0xb9, 0xed, 0x43, 0x62, 0xd1, 0xd0, 0xe6, 0x97, 0xb6, 0xe3, 0x39,
0xdc, 0xed, 0xe5, 0x59, 0x2e, 0x48, 0xf8, 0x9d, 0x04, 0x8c, 0x2e, 0xc3, 0x82, 0x38, 0xf6, 0x0c,
0x66, 0x3b, 0xe1, 0x49, 0xdc, 0x0c, 0xe2, 0x15, 0x58, 0x7c, 0x1a, 0x53, 0x46, 0x4c, 0xeb, 0x10,
0x87, 0xd8, 0x62, 0x34, 0x7d, 0xd6, 0x2c, 0x08, 0xf8, 0x4e, 0x0a, 0x46, 0xdf, 0x80, 0x15, 0x89,
0x4a, 0x22, 0x0b, 0x07, 0x29, 0x05, 0x09, 0x55, 0xd5, 0xbb, 0x2c, 0x56, 0xef, 0x8a, 0xc5, 0x9d,
0x64, 0x0d, 0x69, 0xd0, 0xb1, 0xa8, 0xe7, 0x11, 0x9f, 0x45, 0x22, 0x35, 0x76, 0x8d, 0xf4, 0x37,
0xba, 0x05, 0x6b, 0xd8, 0x75, 0xe9, 0x33, 0x53, 0x50, 0xda, 0x66, 0x49, 0xbb, 0x39, 0x51, 0x94,
0x68, 0x02, 0xe9, 0x33, 0x81, 0x63, 0xe4, 0x15, 0xd5, 0x2e, 0x40, 0x37, 0x3d, 0x47, 0x9e, 0x82,
0x33, 0x0e, 0x29, 0xbe, 0xb5, 0xb3, 0xd0, 0xcf, 0x9e, 0x84, 0xf6, 0xaf, 0x36, 0x2c, 0x55, 0x04,
0x15, 0x7a, 0x0c, 0xc0, 0xbd, 0x55, 0x86, 0x96, 0x72, 0xd7, 0xef, 0x9c, 0x3e, 0x38, 0xb9, 0xbf,
0x4a, 0xb0, 0xc1, 0xbd, 0x5f, 0x7e, 0xa2, 0x9f, 0x43, 0x4f, 0x78, 0xac, 0xe2, 0x2e, 0x5d, 0xf6,
0xe3, 0xaf, 0xc1, 0x9d, 0xeb, 0xaa, 0xd8, 0x8b, 0x18, 0x90, 0xdf, 0xda, 0x3f, 0x5a, 0xd0, 0x4d,
0x05, 0xf3, 0xcb, 0x42, 0x1e, 0x94, 0x38, 0xeb, 0x28, 0xb9, 0x4f, 0x04, 0xec, 0x9e, 0x00, 0xfd,
0x5f, 0xba, 0x92, 0xf6, 0x3e, 0xc0, 0x58, 0xff, 0x4a, 0x15, 0x5a, 0x95, 0x2a, 0xe8, 0x57, 0x60,
0x9e, 0x5b, 0xd6, 0x21, 0xf6, 0x1e, 0x0b, 0x9d, 0x40, 0xdc, 0x95, 0x12, 0x27, 0x52, 0x15, 0x71,
0xf2, 0x73, 0xfb, 0x8f, 0x03, 0xe8, 0x67, 0x5f, 0xf2, 0xe8, 0x4b, 0xe8, 0x65, 0x26, 0x4f, 0xe8,
0xcd, 0xf2, 0xa1, 0x95, 0x27, 0x59, 0xda, 0x5b, 0x13, 0xb0, 0xd4, 0x95, 0x38, 0x85, 0x7c, 0x38,
0x57, 0x1a, 0xdf, 0xa0, 0xab, 0x65, 0xea, 0xba, 0xe1, 0x90, 0x76, 0xad, 0x11, 0x6e, 0x2a, 0x8f,
0xc1, 0x52, 0xc5, 0x3c, 0x06, 0xbd, 0x33, 0x81, 0x4b, 0x6e, 0x26, 0xa4, 0xbd, 0xdb, 0x10, 0x3b,
0x95, 0xfa, 0x14, 0x50, 0x79, 0x58, 0x83, 0xae, 0x4d, 0x64, 0x33, 0x1e, 0x06, 0x69, 0xef, 0x34,
0x43, 0xae, 0x55, 0x54, 0x8e, 0x71, 0x26, 0x2a, 0x9a, 0x1b, 0x14, 0x4d, 0x54, 0xb4, 0x30, 0x1b,
0x9a, 0x42, 0x47, 0xb0, 0x58, 0x1c, 0xf1, 0xa0, 0x2b, 0x75, 0x23, 0xc9, 0xd2, 0x04, 0x49, 0xbb,
0xda, 0x04, 0x35, 0x15, 0x46, 0xe0, 0x6c, 0x7e, 0xa4, 0x82, 0x2e, 0x97, 0xe9, 0x2b, 0x87, 0x4a,
0xda, 0xe6, 0x64, 0xc4, 0xac, 0x4e, 0xc5, 0x31, 0x4b, 0x95, 0x4e, 0x35, 0x33, 0x9c, 0x2a, 0x9d,
0xea, 0xa6, 0x36, 0xfa, 0x14, 0xfa, 0x65, 0xd2, 0xbb, 0x2f, 0x8c, 0x1f, 0xd0, 0x56, 0x1d, 0x9b,
0xea, 0xf9, 0x87, 0x76, 0xbd, 0x31, 0x7e, 0x22, 0xfb, 0x46, 0x8b, 0xc7, 0x7a, 0x66, 0x0a, 0x51,
0x15, 0xeb, 0xe5, 0xb9, 0x46, 0x55, 0xac, 0x57, 0x8d, 0x32, 0xa6, 0xd0, 0x10, 0xe6, 0x73, 0x73,
0x09, 0xf4, 0x76, 0x1d, 0x65, 0xbe, 0xa1, 0xa1, 0x5d, 0x9e, 0x88, 0x97, 0xca, 0x30, 0x93, 0xec,
0xa5, 0xd2, 0x55, 0xed, 0xe6, 0xf2, 0xf9, 0xea, 0xed, 0x49, 0x68, 0xb9, 0x50, 0x2e, 0x4d, 0x2f,
0x2a, 0x43, 0xb9, 0x6e, 0x3a, 0x52, 0x19, 0xca, 0xf5, 0x03, 0x91, 0x29, 0xf4, 0x53, 0x80, 0xf1,
0x84, 0x01, 0x5d, 0xaa, 0xa3, 0xce, 0x9e, 0xfe, 0x9b, 0x27, 0x23, 0xa5, 0xac, 0x9f, 0xc1, 0x72,
0xd5, 0xc3, 0x1f, 0x55, 0x04, 0xfe, 0x09, 0xdd, 0x05, 0x6d, 0xab, 0x29, 0x7a, 0x2a, 0xf8, 0x73,
0xe8, 0x24, 0xd3, 0x01, 0x74, 0xb1, 0x4c, 0x5d, 0x98, 0x87, 0x68, 0xfa, 0x49, 0x28, 0x19, 0x07,
0xf6, 0x92, 0x58, 0x1d, 0xb7, 0xed, 0xeb, 0x63, 0xb5, 0x34, 0x60, 0xa8, 0x8f, 0xd5, 0xf2, 0x14,
0x40, 0x88, 0x4b, 0x9d, 0x21, 0xdb, 0xe5, 0xae, 0x77, 0x86, 0x8a, 0x26, 0x7e, 0xbd, 0x33, 0x54,
0x36, 0xce, 0xa7, 0xd0, 0xaf, 0x60, 0xa5, 0xba, 0xb9, 0x8d, 0x6a, 0x23, 0xbe, 0xa6, 0xc9, 0xae,
0xdd, 0x68, 0x4e, 0x90, 0x8a, 0x7f, 0x91, 0xe4, 0xa7, 0x42, 0x73, 0xbb, 0x3e, 0x3f, 0x55, 0xb7,
0xd8, 0xb5, 0xeb, 0x8d, 0xf1, 0xcb, 0xa1, 0x97, 0xed, 0x22, 0xd7, 0x5b, 0xbb, 0xa2, 0x61, 0x5e,
0x6f, 0xed, 0xca, 0xc6, 0xb4, 0x88, 0x8f, 0xaa, 0x0e, 0x71, 0x55, 0x7c, 0x9c, 0xd0, 0xc2, 0xd6,
0xb6, 0x9a, 0xa2, 0xe7, 0xae, 0xef, 0x72, 0x0b, 0x18, 0x4d, 0xdc, 0x7f, 0x2e, 0x33, 0xbf, 0xdb,
0x10, 0xbb, 0xfe, 0x74, 0x93, 0x4c, 0x3d, 0x51, 0x81, 0x42, 0xc6, 0xbe, 0xde, 0x18, 0x3f, 0x95,
0x1d, 0x24, 0x73, 0xdf, 0x4c, 0xfb, 0x16, 0x5d, 0x9d, 0xc0, 0x27, 0xd3, 0x7e, 0xd6, 0xae, 0x35,
0xc2, 0xad, 0x8a, 0xde, 0x6c, 0x43, 0xf5, 0x24, 0x7f, 0x2a, 0x75, 0x81, 0x4f, 0xf2, 0xa7, 0x8a,
0x1e, 0xed, 0x14, 0xfa, 0xcd, 0x78, 0xa0, 0x57, 0xee, 0x14, 0xa1, 0xed, 0xda, 0x5c, 0x50, 0xdb,
0xb7, 0xd2, 0x6e, 0x9e, 0x8a, 0x26, 0xdd, 0xc8, 0xa7, 0x30, 0x23, 0xde, 0x5a, 0x68, 0xfd, 0xe4,
0x47, 0x98, 0x76, 0xa1, 0x7a, 0x3d, 0x7d, 0x4a, 0x70, 0x4b, 0x0e, 0x67, 0xc5, 0xff, 0xdc, 0x6e,
0xfe, 0x37, 0x00, 0x00, 0xff, 0xff, 0x62, 0x0a, 0xf6, 0x47, 0xfe, 0x26, 0x00, 0x00,
}

View file

@ -0,0 +1,38 @@
package weed_server
import (
"context"
"fmt"
"os"
"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
"github.com/chrislusf/seaweedfs/weed/storage/backend"
"github.com/chrislusf/seaweedfs/weed/storage/needle"
)
// VolumeTierCopyDatToRemote copy dat file to a remote tier
func (vs *VolumeServer) VolumeTierCopyDatToRemote(ctx context.Context, req *volume_server_pb.VolumeTierCopyDatToRemoteRequest) (*volume_server_pb.VolumeTierCopyDatToRemoteResponse, error) {
v := vs.store.GetVolume(needle.VolumeId(req.VolumeId))
if v == nil {
return nil, fmt.Errorf("volume %d not found", req.VolumeId)
}
if v.Collection != req.Collection {
return nil, fmt.Errorf("existing collection:%v unexpected input: %v", v.Collection, req.Collection)
}
diskFile, ok := v.DataBackend.(*backend.DiskFile)
if !ok {
return nil, fmt.Errorf("volume %d is not on local disk", req.VolumeId)
}
err := uploadFileToRemote(ctx, req, diskFile.File)
return &volume_server_pb.VolumeTierCopyDatToRemoteResponse{}, err
}
func uploadFileToRemote(ctx context.Context, req *volume_server_pb.VolumeTierCopyDatToRemoteRequest, f *os.File) error {
println("copying dat file of", f.Name(), "to remote")
return nil
}

View file

@ -0,0 +1,112 @@
package shell
import (
"context"
"flag"
"fmt"
"io"
"time"
"github.com/chrislusf/seaweedfs/weed/operation"
"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
"github.com/chrislusf/seaweedfs/weed/storage/needle"
"google.golang.org/grpc"
)
func init() {
Commands = append(Commands, &commandVolumeTier{})
}
type commandVolumeTier struct {
}
func (c *commandVolumeTier) Name() string {
return "volume.tier"
}
func (c *commandVolumeTier) Help() string {
return `copy the dat file of a volume to a remote tier
ec.encode [-collection=""] [-fullPercent=95] [-quietFor=1h]
ec.encode [-collection=""] [-volumeId=<volume_id>]
This command will:
1. freeze one volume
2. copy the dat file of a volume to a remote tier
`
}
func (c *commandVolumeTier) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) {
tierCommand := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
volumeId := tierCommand.Int("volumeId", 0, "the volume id")
collection := tierCommand.String("collection", "", "the collection name")
fullPercentage := tierCommand.Float64("fullPercent", 95, "the volume reaches the percentage of max volume size")
quietPeriod := tierCommand.Duration("quietFor", 24*time.Hour, "select volumes without no writes for this period")
dest := tierCommand.String("destination", "", "the target tier name")
if err = tierCommand.Parse(args); err != nil {
return nil
}
ctx := context.Background()
vid := needle.VolumeId(*volumeId)
// volumeId is provided
if vid != 0 {
return doVolumeTier(ctx, commandEnv, *collection, vid, *dest)
}
// apply to all volumes in the collection
// reusing collectVolumeIdsForEcEncode for now
volumeIds, err := collectVolumeIdsForEcEncode(ctx, commandEnv, *collection, *fullPercentage, *quietPeriod)
if err != nil {
return err
}
fmt.Printf("tiering volumes: %v\n", volumeIds)
for _, vid := range volumeIds {
if err = doVolumeTier(ctx, commandEnv, *collection, vid, *dest); err != nil {
return err
}
}
return nil
}
func doVolumeTier(ctx context.Context, commandEnv *CommandEnv, collection string, vid needle.VolumeId, dest string) (err error) {
// find volume location
locations, found := commandEnv.MasterClient.GetLocations(uint32(vid))
if !found {
return fmt.Errorf("volume %d not found", vid)
}
// mark the volume as readonly
/*
err = markVolumeReadonly(ctx, commandEnv.option.GrpcDialOption, needle.VolumeId(vid), locations)
if err != nil {
return fmt.Errorf("mark volume %d as readonly on %s: %v", vid, locations[0].Url, err)
}
*/
// copy the .dat file to remote tier
err = copyDatToRemoteTier(ctx, commandEnv.option.GrpcDialOption, needle.VolumeId(vid), collection, locations[0].Url, dest)
if err != nil {
return fmt.Errorf("copy dat file for volume %d on %s to %s: %v", vid, locations[0].Url, dest, err)
}
return nil
}
func copyDatToRemoteTier(ctx context.Context, grpcDialOption grpc.DialOption, volumeId needle.VolumeId, collection string, sourceVolumeServer string, dest string) error {
err := operation.WithVolumeServerClient(sourceVolumeServer, grpcDialOption, func(volumeServerClient volume_server_pb.VolumeServerClient) error {
_, copyErr := volumeServerClient.VolumeTierCopyDatToRemote(ctx, &volume_server_pb.VolumeTierCopyDatToRemoteRequest{
VolumeId: uint32(volumeId),
Collection: collection,
})
return copyErr
})
return err
}

View file

@ -2,6 +2,7 @@ package backend
import (
"io"
"os"
"time"
)
@ -12,6 +13,7 @@ type DataStorageBackend interface {
io.Closer
GetStat() (datSize int64, modTime time.Time, err error)
String() string
Instantiate(src *os.File) error
}
var (

View file

@ -48,3 +48,7 @@ func (df *DiskFile) GetStat() (datSize int64, modTime time.Time, err error) {
func (df *DiskFile) String() string {
return df.fullFilePath
}
func (df *DiskFile) Instantiate(src *os.File) error {
panic("should not implement Instantiate for DiskFile")
}

View file

@ -58,3 +58,7 @@ func (mmf *MemoryMappedFile) GetStat() (datSize int64, modTime time.Time, err er
func (mmf *MemoryMappedFile) String() string {
return mmf.mm.File.Name()
}
func (mmf *MemoryMappedFile) Instantiate(src *os.File) error {
panic("should not implement Instantiate for MemoryMappedFile")
}

View file

@ -2,6 +2,7 @@ package s3_backend
import (
"fmt"
"os"
"strings"
"time"
@ -25,7 +26,6 @@ type S3Backend struct {
conn s3iface.S3API
region string
bucket string
dir string
vid needle.VolumeId
key string
}
@ -84,11 +84,11 @@ func (s3backend *S3Backend) GetName() string {
return "s3"
}
func (s3backend *S3Backend) GetSinkToDirectory() string {
return s3backend.dir
func (s3backend S3Backend) Instantiate(src *os.File) error {
panic("implement me")
}
func (s3backend *S3Backend) Initialize(configuration util.Configuration, vid needle.VolumeId) error {
func (s3backend *S3Backend) Initialize(configuration util.Configuration, prefix string, vid needle.VolumeId) error {
glog.V(0).Infof("storage.backend.s3.region: %v", configuration.GetString("region"))
glog.V(0).Infof("storage.backend.s3.bucket: %v", configuration.GetString("bucket"))
glog.V(0).Infof("storage.backend.s3.directory: %v", configuration.GetString("directory"))
@ -98,20 +98,19 @@ func (s3backend *S3Backend) Initialize(configuration util.Configuration, vid nee
configuration.GetString("aws_secret_access_key"),
configuration.GetString("region"),
configuration.GetString("bucket"),
configuration.GetString("directory"),
prefix,
vid,
)
}
func (s3backend *S3Backend) initialize(awsAccessKeyId, awsSecretAccessKey, region, bucket, dir string,
vid needle.VolumeId) (err error) {
func (s3backend *S3Backend) initialize(awsAccessKeyId, awsSecretAccessKey, region, bucket string,
prefix string, vid needle.VolumeId) (err error) {
s3backend.region = region
s3backend.bucket = bucket
s3backend.dir = dir
s3backend.conn, err = createSession(awsAccessKeyId, awsSecretAccessKey, region)
s3backend.vid = vid
s3backend.key = fmt.Sprintf("%s/%d.dat", dir, vid)
s3backend.key = fmt.Sprintf("%s_%d.dat", prefix, vid)
if strings.HasPrefix(s3backend.key, "/") {
s3backend.key = s3backend.key[1:]
}

View file

@ -0,0 +1,56 @@
package s3_backend
import (
"fmt"
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3/s3iface"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
)
func uploadToS3(sess s3iface.S3API, filename string, destBucket string, destKey string) error {
//open the file
f, err := os.Open(filename)
if err != nil {
return fmt.Errorf("failed to open file %q, %v", filename, err)
}
defer f.Close()
info, err := f.Stat()
if err != nil {
return fmt.Errorf("failed to stat file %q, %v", filename, err)
}
fileSize := info.Size()
partSize := int64(64 * 1024 * 1024) // The minimum/default allowed part size is 5MB
for partSize*1000 < fileSize {
partSize *= 4
}
// Create an uploader with the session and custom options
uploader := s3manager.NewUploaderWithClient(sess, func(u *s3manager.Uploader) {
u.PartSize = partSize
u.Concurrency = 15 // default is 15
})
// Upload the file to S3.
result, err := uploader.Upload(&s3manager.UploadInput{
Bucket: aws.String(destBucket),
Key: aws.String(destKey),
Body: f,
ACL: aws.String("private"),
ServerSideEncryption: aws.String("AES256"),
StorageClass: aws.String("STANDARD_IA"),
})
//in case it fails to upload
if err != nil {
return fmt.Errorf("failed to upload file, %v", err)
}
fmt.Printf("file %s uploaded to %s\n", filename, result.Location)
return nil
}