diff --git a/internal/testplanet/uplink_test.go b/internal/testplanet/uplink_test.go index 19087c384..62d990ff7 100644 --- a/internal/testplanet/uplink_test.go +++ b/internal/testplanet/uplink_test.go @@ -91,7 +91,7 @@ func TestDownloadWithSomeNodesOffline(t *testing.T) { // get a remote segment from pointerdb pdb := satellite.Metainfo.Service - listResponse, _, err := pdb.List(ctx, "", "", "", true, 0, 0) + listResponse, _, err := pdb.List(ctx, "", "", true, 0, 0) require.NoError(t, err) var path string @@ -195,7 +195,7 @@ func TestDownloadFromUnresponsiveNode(t *testing.T) { // get a remote segment from pointerdb pdb := planet.Satellites[0].Metainfo.Service - listResponse, _, err := pdb.List(ctx, "", "", "", true, 0, 0) + listResponse, _, err := pdb.List(ctx, "", "", true, 0, 0) require.NoError(t, err) var path string diff --git a/pkg/pb/metainfo.pb.go b/pkg/pb/metainfo.pb.go index 33e921d4a..a7eeb48c2 100644 --- a/pkg/pb/metainfo.pb.go +++ b/pkg/pb/metainfo.pb.go @@ -1310,7 +1310,7 @@ type ListSegmentsRequestOld struct { Bucket []byte `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"` Prefix []byte `protobuf:"bytes,2,opt,name=prefix,proto3" json:"prefix,omitempty"` StartAfter []byte `protobuf:"bytes,3,opt,name=start_after,json=startAfter,proto3" json:"start_after,omitempty"` - EndBefore []byte `protobuf:"bytes,4,opt,name=end_before,json=endBefore,proto3" json:"end_before,omitempty"` + EndBefore []byte `protobuf:"bytes,4,opt,name=end_before,json=endBefore,proto3" json:"end_before,omitempty"` // Deprecated: Do not use. Recursive bool `protobuf:"varint,5,opt,name=recursive,proto3" json:"recursive,omitempty"` Limit int32 `protobuf:"varint,6,opt,name=limit,proto3" json:"limit,omitempty"` MetaFlags uint32 `protobuf:"fixed32,7,opt,name=meta_flags,json=metaFlags,proto3" json:"meta_flags,omitempty"` @@ -1371,6 +1371,7 @@ func (m *ListSegmentsRequestOld) GetStartAfter() []byte { return nil } +// Deprecated: Do not use. func (m *ListSegmentsRequestOld) GetEndBefore() []byte { if m != nil { return m.EndBefore @@ -5133,239 +5134,239 @@ func init() { func init() { proto.RegisterFile("metainfo.proto", fileDescriptor_631e2f30a93cd64e) } var fileDescriptor_631e2f30a93cd64e = []byte{ - // 3709 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5b, 0x4b, 0x6c, 0x1c, 0x59, - 0xd5, 0x76, 0xbf, 0xbb, 0x4f, 0xb7, 0xdd, 0xdd, 0xd7, 0x8e, 0xdd, 0x29, 0xc7, 0x71, 0x52, 0x49, - 0x66, 0xfc, 0xeb, 0x9f, 0x71, 0x46, 0x9e, 0xff, 0x47, 0x83, 0x92, 0x61, 0xb0, 0xd3, 0x9e, 0x74, - 0x4f, 0x62, 0xc7, 0x53, 0x4e, 0x26, 0x21, 0x0c, 0xb4, 0xca, 0x5d, 0xd7, 0x76, 0x91, 0xee, 0xae, - 0xa6, 0xaa, 0x7a, 0xc6, 0x19, 0x56, 0x48, 0x23, 0x21, 0x04, 0x42, 0x23, 0xd6, 0x88, 0xd5, 0xec, - 0x58, 0xc1, 0x0e, 0x09, 0xd8, 0x02, 0x12, 0x1a, 0xa4, 0x11, 0x62, 0xc1, 0x62, 0x60, 0xc5, 0x0e, - 0x36, 0xec, 0x40, 0x48, 0xe8, 0xbe, 0xea, 0x5d, 0xfd, 0xf0, 0x23, 0x61, 0x76, 0x55, 0xe7, 0x9e, - 0x7b, 0xea, 0xde, 0xf3, 0xf8, 0xce, 0xa9, 0x73, 0xab, 0x60, 0xa6, 0x8b, 0x6d, 0x55, 0xef, 0xed, - 0x1b, 0xab, 0x7d, 0xd3, 0xb0, 0x0d, 0x94, 0x17, 0xf7, 0x52, 0x05, 0xf7, 0xda, 0xe6, 0xd3, 0xbe, - 0xad, 0x1b, 0x3d, 0x36, 0x26, 0xc1, 0x81, 0x71, 0xc0, 0xf9, 0xa4, 0xe5, 0x03, 0xc3, 0x38, 0xe8, - 0xe0, 0xeb, 0xf4, 0x6e, 0x6f, 0xb0, 0x7f, 0xdd, 0xd6, 0xbb, 0xd8, 0xb2, 0xd5, 0x6e, 0x5f, 0x30, - 0xf7, 0x0c, 0x0d, 0xf3, 0xeb, 0x72, 0xdf, 0xd0, 0x7b, 0x36, 0x36, 0xb5, 0x3d, 0x4e, 0x28, 0x19, - 0xa6, 0x86, 0x4d, 0x8b, 0xdd, 0xc9, 0x2b, 0x30, 0xad, 0xe0, 0x6f, 0x0e, 0xb0, 0x65, 0x37, 0xb0, - 0xaa, 0x61, 0x13, 0x2d, 0x40, 0x4e, 0xed, 0xeb, 0xad, 0x27, 0xf8, 0x69, 0x2d, 0x71, 0x29, 0xb1, - 0x52, 0x52, 0xb2, 0x6a, 0x5f, 0xbf, 0x83, 0x9f, 0xca, 0x3f, 0x49, 0x41, 0x76, 0x63, 0xd0, 0x7e, - 0x82, 0x6d, 0x84, 0x20, 0xdd, 0x53, 0xbb, 0x98, 0x33, 0xd0, 0x6b, 0xf4, 0x1a, 0x14, 0xfb, 0xaa, - 0x7d, 0xd8, 0x6a, 0xeb, 0xfd, 0x43, 0x6c, 0xd6, 0x92, 0x97, 0x12, 0x2b, 0x33, 0x6b, 0x0b, 0xab, - 0x9e, 0x8d, 0xdc, 0xa2, 0x23, 0xbb, 0x03, 0xdd, 0xc6, 0x0a, 0x10, 0x5e, 0x46, 0x40, 0xb7, 0x00, - 0xda, 0x26, 0x56, 0x6d, 0xac, 0xb5, 0x54, 0xbb, 0x96, 0xba, 0x94, 0x58, 0x29, 0xae, 0x49, 0xab, - 0x6c, 0x8f, 0xab, 0x62, 0x8f, 0xab, 0xf7, 0xc5, 0x1e, 0x37, 0xf2, 0xbf, 0xf9, 0x6c, 0x79, 0xea, - 0xa3, 0x3f, 0x2f, 0x27, 0x94, 0x02, 0x9f, 0xb7, 0x6e, 0xa3, 0x57, 0x60, 0x4e, 0xc3, 0xfb, 0xea, - 0xa0, 0x63, 0xb7, 0x2c, 0x7c, 0xd0, 0xc5, 0x3d, 0xbb, 0x65, 0xe9, 0x1f, 0xe0, 0x5a, 0xfa, 0x52, - 0x62, 0x25, 0xa5, 0x20, 0x3e, 0xb6, 0xcb, 0x86, 0x76, 0xf5, 0x0f, 0x30, 0x7a, 0x08, 0xe7, 0xc5, - 0x0c, 0x13, 0x6b, 0x83, 0x9e, 0xa6, 0xf6, 0xda, 0x4f, 0x5b, 0x56, 0xfb, 0x10, 0x77, 0x71, 0x2d, - 0x43, 0x57, 0xb1, 0xb8, 0xea, 0x2a, 0x4f, 0x71, 0x78, 0x76, 0x29, 0x8b, 0xb2, 0xc0, 0x67, 0x07, - 0x07, 0x90, 0x06, 0x4b, 0x42, 0xb0, 0xbb, 0xfb, 0x56, 0x5f, 0x35, 0xd5, 0x2e, 0xb6, 0xb1, 0x69, - 0xd5, 0xb2, 0x54, 0xf8, 0x25, 0xaf, 0x6e, 0x36, 0x9d, 0xcb, 0x1d, 0x87, 0x4f, 0x59, 0xe4, 0x62, - 0xa2, 0x06, 0xd1, 0x12, 0x40, 0x5f, 0x35, 0xed, 0x1e, 0x36, 0x5b, 0xba, 0x56, 0xcb, 0x51, 0x4b, - 0x14, 0x38, 0xa5, 0xa9, 0xc9, 0x3a, 0xcc, 0x30, 0x63, 0xdd, 0xd5, 0x2d, 0xbb, 0x69, 0xe3, 0x6e, - 0xa4, 0xd1, 0xfc, 0xaa, 0x4f, 0x1e, 0x4b, 0xf5, 0xf2, 0xc7, 0x29, 0x98, 0x65, 0xcf, 0xba, 0x45, - 0x69, 0xdc, 0x9f, 0xd0, 0x75, 0xc8, 0x1e, 0x52, 0x9f, 0xaa, 0x95, 0xa9, 0xe0, 0x85, 0x55, 0xc7, - 0xdf, 0x7d, 0x2e, 0xa7, 0x70, 0xb6, 0x53, 0x76, 0xab, 0x38, 0x8f, 0x48, 0x1d, 0xcf, 0x23, 0xd2, - 0x67, 0xe9, 0x11, 0x99, 0xd3, 0xf7, 0x88, 0x6c, 0xd0, 0x23, 0xbe, 0x0c, 0x73, 0x7e, 0x2b, 0x59, - 0x7d, 0xa3, 0x67, 0x61, 0xb4, 0x02, 0xd9, 0x3d, 0x4a, 0xa7, 0x7a, 0x2f, 0xae, 0x55, 0x5c, 0x33, - 0x31, 0x7e, 0x85, 0x8f, 0xcb, 0x0f, 0xa1, 0xc2, 0x28, 0xb7, 0xb1, 0x7d, 0x9a, 0x46, 0x96, 0x5f, - 0x87, 0xaa, 0x47, 0xf0, 0xc4, 0xeb, 0x7a, 0x2c, 0xfc, 0xaf, 0x8e, 0x3b, 0xf8, 0x74, 0xfd, 0x4f, - 0x9e, 0x17, 0x5a, 0x13, 0xb2, 0xd9, 0xea, 0xe4, 0x8f, 0x12, 0x62, 0xcd, 0x24, 0xc0, 0x8e, 0xfd, - 0xc8, 0x79, 0xc8, 0xb6, 0x07, 0xa6, 0x65, 0x98, 0x02, 0x6c, 0xd9, 0x1d, 0x9a, 0x83, 0x4c, 0x47, - 0xef, 0xea, 0x2c, 0x26, 0x33, 0x0a, 0xbb, 0x41, 0x17, 0xa0, 0xa0, 0xe9, 0x26, 0x6e, 0x13, 0xc3, - 0x53, 0x3f, 0xce, 0x28, 0x2e, 0x41, 0x7e, 0x04, 0xc8, 0xbb, 0x22, 0xae, 0xc6, 0x55, 0xc8, 0xe8, - 0x36, 0xee, 0x5a, 0xb5, 0xc4, 0xa5, 0xd4, 0x4a, 0x71, 0xad, 0x16, 0xd4, 0xa2, 0xc0, 0x07, 0x85, - 0xb1, 0x11, 0x25, 0x74, 0x0d, 0x13, 0xd3, 0x07, 0xe7, 0x15, 0x7a, 0x2d, 0x7f, 0x3b, 0x01, 0x8b, - 0x8c, 0x7b, 0x17, 0xdb, 0xeb, 0xb6, 0x6d, 0xea, 0x7b, 0x03, 0xf2, 0xc8, 0x53, 0x8d, 0x74, 0xbf, - 0xfb, 0x26, 0x83, 0xee, 0x7b, 0x11, 0x2e, 0x44, 0x2f, 0x81, 0x1b, 0xe4, 0xc3, 0x04, 0xcc, 0xae, - 0x6b, 0x9a, 0x89, 0x2d, 0x0b, 0x6b, 0xf7, 0x48, 0x8a, 0xbb, 0x4b, 0x75, 0xb6, 0x22, 0x34, 0xc9, - 0xbc, 0x08, 0xad, 0xf2, 0xf4, 0xe7, 0xb2, 0x08, 0xed, 0xde, 0x82, 0x39, 0xcb, 0x36, 0x4c, 0xf5, - 0x00, 0xb7, 0x48, 0xfe, 0x6c, 0xa9, 0x4c, 0x1a, 0x87, 0xc5, 0xea, 0x2a, 0x4d, 0xaa, 0xdb, 0x86, - 0x86, 0xf9, 0x63, 0x14, 0xc4, 0xd9, 0x3d, 0x34, 0xf9, 0xf7, 0x49, 0x98, 0xe7, 0x98, 0xf2, 0xd0, - 0xd4, 0x1d, 0x67, 0xbc, 0xd7, 0xd1, 0x8e, 0xe5, 0x1c, 0x9e, 0x08, 0x28, 0x09, 0x7f, 0x27, 0xda, - 0x23, 0x38, 0xc7, 0x75, 0x44, 0xaf, 0x51, 0x0d, 0x72, 0x1c, 0xe5, 0x38, 0xc0, 0x89, 0x5b, 0x74, - 0x03, 0xc0, 0x45, 0xb3, 0x71, 0x60, 0xcc, 0xc3, 0x8e, 0x6e, 0x80, 0xd4, 0x55, 0x8f, 0x04, 0x6a, - 0x61, 0xcd, 0x0f, 0xa5, 0x19, 0xfa, 0xa4, 0x85, 0xae, 0x7a, 0xb4, 0x29, 0x18, 0xbc, 0x78, 0x5a, - 0x07, 0xc0, 0x47, 0x7d, 0xdd, 0x54, 0xa9, 0xbf, 0x66, 0x27, 0xc8, 0x2e, 0x9e, 0x79, 0xf2, 0xa7, - 0x09, 0x58, 0xf0, 0x6b, 0x94, 0x59, 0x9c, 0xa8, 0xb4, 0x01, 0x15, 0x55, 0xd8, 0xbc, 0x45, 0xad, - 0x28, 0xfc, 0x7c, 0xc9, 0x55, 0x6e, 0x84, 0x57, 0x28, 0x65, 0x67, 0x1a, 0xbd, 0xb7, 0xd0, 0xab, - 0x30, 0x6d, 0x1a, 0x86, 0xdd, 0xea, 0xeb, 0xb8, 0x8d, 0x1d, 0x07, 0xdc, 0x28, 0x93, 0x25, 0xfd, - 0xe9, 0xb3, 0xe5, 0xdc, 0x0e, 0xa1, 0x37, 0xeb, 0x4a, 0x91, 0x70, 0xb1, 0x1b, 0x8d, 0x26, 0x27, - 0x53, 0x7f, 0x4f, 0xb5, 0x31, 0xad, 0x97, 0x52, 0x74, 0xca, 0x02, 0x9f, 0x52, 0xa6, 0x5c, 0x3b, - 0x6c, 0xfc, 0x0e, 0x7e, 0xaa, 0x40, 0xdf, 0xb9, 0x96, 0xff, 0xe5, 0x6e, 0xea, 0x96, 0xd1, 0x25, - 0x2b, 0x7a, 0xee, 0x7e, 0xf2, 0x12, 0xe4, 0xb8, 0x53, 0x70, 0x27, 0x41, 0x1e, 0x27, 0xd9, 0x61, - 0x57, 0x8a, 0x60, 0x41, 0x37, 0xa0, 0x6c, 0x98, 0xfa, 0x81, 0xde, 0x53, 0x3b, 0x42, 0xf1, 0x19, - 0xaa, 0xf8, 0xa8, 0x00, 0x9b, 0x11, 0xac, 0x4c, 0xd9, 0x72, 0x03, 0x6a, 0x81, 0xcd, 0xbb, 0x26, - 0xf5, 0x2c, 0x23, 0x31, 0x72, 0x19, 0xf2, 0x0f, 0x13, 0x70, 0x9e, 0x8b, 0xaa, 0x1b, 0xef, 0xf7, - 0x3a, 0x86, 0xaa, 0x3d, 0x77, 0x4d, 0xca, 0x9f, 0x24, 0x40, 0x0a, 0x2d, 0xea, 0x2c, 0x9c, 0xd6, - 0xa3, 0xab, 0xe4, 0x68, 0x93, 0x1d, 0xdf, 0x5b, 0x7f, 0x90, 0x80, 0x73, 0x7c, 0x43, 0xcd, 0xde, - 0xbe, 0xf1, 0xfc, 0x35, 0xfc, 0xa6, 0x03, 0xb2, 0x6c, 0x3d, 0x91, 0xee, 0x33, 0x5a, 0x25, 0x24, - 0x8b, 0x8b, 0x30, 0xf4, 0xd5, 0x0e, 0xcf, 0x71, 0x6b, 0x3f, 0x4e, 0x38, 0xc1, 0xe1, 0x2f, 0x39, - 0x4e, 0xd7, 0x75, 0x02, 0xce, 0x90, 0x1c, 0xdf, 0x19, 0xbe, 0x9f, 0x84, 0x79, 0x52, 0x34, 0xf0, - 0x45, 0x5a, 0x67, 0xa1, 0xb2, 0x79, 0xc8, 0xf6, 0x4d, 0xbc, 0xaf, 0x1f, 0x71, 0xa5, 0xf1, 0x3b, - 0xb4, 0x0c, 0x45, 0xcb, 0x56, 0x4d, 0xbb, 0xa5, 0xee, 0x13, 0x0b, 0x53, 0x17, 0x56, 0x80, 0x92, - 0xd6, 0x09, 0x85, 0x14, 0x11, 0xb8, 0xa7, 0xb5, 0xf6, 0xf0, 0x3e, 0xa9, 0x61, 0xd2, 0xac, 0x88, - 0xc0, 0x3d, 0x6d, 0x83, 0x12, 0x48, 0x01, 0x65, 0x62, 0x52, 0x62, 0xe9, 0xef, 0xb1, 0xec, 0x95, - 0x57, 0x5c, 0x82, 0x5b, 0x74, 0x65, 0xbd, 0x45, 0xd7, 0x12, 0x00, 0xd9, 0x45, 0x6b, 0xbf, 0xa3, - 0x1e, 0x58, 0xf4, 0x45, 0x2b, 0xa7, 0x14, 0x08, 0xe5, 0x4d, 0x42, 0xa0, 0xe9, 0xc9, 0xaf, 0x0e, - 0xd7, 0x5c, 0x37, 0xfd, 0xb5, 0xd7, 0x0b, 0xae, 0x3a, 0x62, 0x66, 0xac, 0x8e, 0xa8, 0xc4, 0x24, - 0x0c, 0x69, 0xf1, 0x32, 0x47, 0x7d, 0x2a, 0xe1, 0xf1, 0xa9, 0xc9, 0xd0, 0x60, 0x11, 0x0a, 0xba, - 0xd5, 0xe2, 0x5a, 0x4e, 0xd1, 0x47, 0xe4, 0x75, 0x6b, 0x87, 0xde, 0xcb, 0xdf, 0xa3, 0x4e, 0x18, - 0x51, 0xea, 0x1d, 0xcb, 0xca, 0xcb, 0x50, 0x64, 0x76, 0x6d, 0x79, 0x8a, 0x3e, 0x60, 0xa4, 0xed, - 0x31, 0x4a, 0xbf, 0x45, 0x82, 0xf1, 0x51, 0x45, 0xdf, 0xbd, 0x8e, 0x26, 0x6f, 0x02, 0xda, 0x31, - 0x8d, 0x6f, 0xe0, 0xb6, 0x17, 0x9a, 0x26, 0x5e, 0xa3, 0xfc, 0x1a, 0xcc, 0xfa, 0xc4, 0xf0, 0xea, - 0xf9, 0x32, 0x94, 0xfa, 0x8c, 0xdc, 0xb2, 0xd4, 0x8e, 0x70, 0xd3, 0x22, 0xa7, 0xed, 0xaa, 0x1d, - 0x5b, 0xfe, 0x6e, 0x0e, 0xb2, 0xf7, 0xf6, 0xc8, 0x6d, 0xac, 0x3b, 0x5f, 0x83, 0x19, 0xb7, 0x82, - 0xf2, 0x60, 0xc1, 0xb4, 0x43, 0xdd, 0xe1, 0xa0, 0xf0, 0x1e, 0x36, 0x2d, 0xb7, 0xb8, 0x17, 0xb7, - 0x64, 0x3b, 0x96, 0xad, 0xda, 0x03, 0x8b, 0xba, 0xf4, 0x8c, 0x77, 0x3b, 0xec, 0xd1, 0xab, 0xbb, - 0x74, 0x58, 0xe1, 0x6c, 0xe8, 0x65, 0x28, 0x58, 0xb6, 0x89, 0xd5, 0x2e, 0x51, 0x68, 0x86, 0x06, - 0x77, 0x85, 0x07, 0x77, 0x7e, 0x97, 0x0e, 0x34, 0xeb, 0x4a, 0x9e, 0xb1, 0x34, 0xb5, 0x40, 0x1f, - 0x20, 0x7b, 0xbc, 0x16, 0xcc, 0x3a, 0x79, 0x26, 0x79, 0x3a, 0x91, 0x91, 0x9b, 0x40, 0x46, 0x9e, - 0x4d, 0x5b, 0x27, 0x25, 0x38, 0xab, 0xfc, 0x30, 0x95, 0x91, 0x9f, 0x64, 0x1d, 0x7c, 0xde, 0xba, - 0x8d, 0x6e, 0x43, 0xcd, 0xd5, 0x36, 0xd1, 0x93, 0xa6, 0xda, 0x6a, 0xab, 0x67, 0xf4, 0xda, 0xb8, - 0x56, 0xa0, 0xaa, 0x98, 0xe6, 0xaa, 0xc8, 0x6c, 0x13, 0xa2, 0x32, 0xef, 0xb0, 0x6f, 0x71, 0x6e, - 0x4a, 0x47, 0x2f, 0x03, 0x0a, 0x0b, 0xaa, 0x01, 0x35, 0x5d, 0x35, 0x34, 0x07, 0xbd, 0x04, 0x68, - 0x5f, 0x3f, 0x0a, 0xd6, 0xc8, 0x45, 0x0a, 0xef, 0x15, 0x3a, 0xe2, 0x2d, 0x8e, 0x1b, 0x50, 0x0d, - 0x37, 0x19, 0x4a, 0xa3, 0xab, 0xf3, 0x8a, 0x19, 0xec, 0x2e, 0x3c, 0x80, 0x73, 0xd1, 0x5d, 0x85, - 0xe9, 0x31, 0xbb, 0x0a, 0x73, 0x38, 0xa6, 0x9d, 0x60, 0x1b, 0xb6, 0xda, 0x61, 0xdb, 0x98, 0xa1, - 0xdb, 0x28, 0x50, 0x0a, 0x5d, 0xff, 0x32, 0x14, 0xf5, 0x5e, 0x47, 0xef, 0x61, 0x36, 0x5e, 0xa6, - 0xe3, 0xc0, 0x48, 0x82, 0xc1, 0xc4, 0x5d, 0xc3, 0xe6, 0x0c, 0x15, 0xc6, 0xc0, 0x48, 0x84, 0x41, - 0x7e, 0x1b, 0xb2, 0xcc, 0x6b, 0x51, 0x11, 0x72, 0xcd, 0xed, 0x77, 0xd6, 0xef, 0x36, 0xeb, 0x95, - 0x29, 0x34, 0x0d, 0x85, 0x07, 0x3b, 0x77, 0xef, 0xad, 0xd7, 0x9b, 0xdb, 0xb7, 0x2b, 0x09, 0x34, - 0x03, 0x70, 0xeb, 0xde, 0xd6, 0x56, 0xf3, 0xfe, 0x7d, 0x72, 0x9f, 0x24, 0xc3, 0xfc, 0x7e, 0xb3, - 0x5e, 0x49, 0xa1, 0x12, 0xe4, 0xeb, 0x9b, 0x77, 0x37, 0xe9, 0x60, 0x5a, 0xfe, 0x30, 0x05, 0x88, - 0x05, 0xc4, 0x06, 0x3e, 0xd0, 0x7b, 0x27, 0x79, 0x2d, 0x3f, 0x9b, 0x40, 0xf6, 0x3b, 0x78, 0xfa, - 0x78, 0x0e, 0x1e, 0xe9, 0x3a, 0xb9, 0x53, 0x75, 0x9d, 0xfc, 0x49, 0x5c, 0x47, 0xfe, 0x55, 0x12, - 0x66, 0x7d, 0x66, 0xe0, 0x68, 0x7a, 0x66, 0x6a, 0xf5, 0xc1, 0x5d, 0x7a, 0x24, 0xdc, 0x45, 0x2a, - 0x30, 0x73, 0xaa, 0x0a, 0xcc, 0x9e, 0x48, 0x81, 0x7f, 0x4b, 0x08, 0x05, 0xfa, 0xde, 0x0e, 0x27, - 0x77, 0x64, 0x9f, 0x62, 0x12, 0x23, 0x15, 0x33, 0x0c, 0x3a, 0x93, 0x27, 0x87, 0xce, 0x54, 0x0c, - 0x74, 0xca, 0xf3, 0x30, 0xe7, 0xdf, 0x2e, 0x6f, 0xea, 0xfc, 0x28, 0x01, 0x15, 0x36, 0x70, 0x92, - 0x96, 0xe3, 0x59, 0xb9, 0x9d, 0xfc, 0x3a, 0x54, 0x3d, 0xab, 0x73, 0xfb, 0x96, 0x06, 0x25, 0x86, - 0xfb, 0x96, 0x8c, 0x59, 0xe1, 0xe3, 0xf2, 0x4f, 0x93, 0x62, 0xfe, 0x49, 0x7b, 0x88, 0x91, 0xdb, - 0xfb, 0x1f, 0xa8, 0x78, 0xb6, 0xe7, 0x2d, 0xa7, 0xcb, 0xee, 0x06, 0x59, 0x5d, 0xed, 0x63, 0xe5, - 0x0d, 0xc9, 0x54, 0x80, 0xf5, 0x16, 0xeb, 0x4c, 0xfa, 0x4a, 0xe8, 0x74, 0x6c, 0x09, 0x9d, 0xf1, - 0x96, 0xd0, 0x4d, 0x28, 0xb3, 0x2d, 0xb7, 0xf4, 0x5e, 0xbb, 0x33, 0xd0, 0xb0, 0x1b, 0x1f, 0x01, - 0xdd, 0x88, 0x6e, 0x64, 0x93, 0xf3, 0x29, 0x33, 0x6c, 0xa2, 0xb8, 0x97, 0x1f, 0x09, 0x80, 0x1f, - 0xb3, 0xc9, 0xe9, 0x17, 0x3b, 0xac, 0xc9, 0xf9, 0xeb, 0x14, 0xcc, 0xf8, 0xb9, 0x23, 0x1c, 0x24, - 0x31, 0xc2, 0x41, 0x92, 0x71, 0x75, 0x5b, 0x6a, 0xbc, 0xba, 0xcd, 0x5f, 0x88, 0xa5, 0x4f, 0xa1, - 0x10, 0xcb, 0x9c, 0x42, 0x21, 0x96, 0x3d, 0xfd, 0x42, 0x2c, 0x77, 0x72, 0x34, 0xc9, 0xc7, 0xa1, - 0xc9, 0xff, 0xc1, 0x7c, 0xb4, 0x37, 0x21, 0x09, 0xf2, 0xce, 0xf4, 0x04, 0x7b, 0xe7, 0x11, 0xf7, - 0xf2, 0xc7, 0x09, 0xa8, 0x79, 0x92, 0xd6, 0x09, 0xcf, 0x12, 0xce, 0x0c, 0x73, 0xde, 0x82, 0xf3, - 0x11, 0xab, 0xe4, 0x71, 0x30, 0x19, 0xdc, 0xcb, 0xdf, 0x12, 0xb2, 0xde, 0xd4, 0x7b, 0xba, 0x75, - 0x78, 0xc2, 0x2d, 0x4f, 0xf8, 0xf0, 0x0b, 0x20, 0x45, 0x3d, 0x9c, 0x23, 0xff, 0xdf, 0x93, 0x50, - 0xdc, 0x55, 0x6d, 0x31, 0xef, 0xec, 0x4a, 0x87, 0x13, 0xb5, 0xc7, 0x9b, 0x30, 0x4d, 0xc3, 0x8e, - 0x24, 0x7f, 0x4d, 0xb5, 0xf1, 0x44, 0xd1, 0x56, 0x12, 0x53, 0xeb, 0xaa, 0x8d, 0xd1, 0x16, 0x94, - 0xdd, 0xa6, 0x37, 0x13, 0x36, 0x49, 0xd8, 0xcd, 0xb8, 0x93, 0xa9, 0xb8, 0xeb, 0x30, 0x6b, 0xa9, - 0x36, 0xee, 0x74, 0x74, 0x5a, 0x80, 0x1f, 0xf4, 0x54, 0x7b, 0x60, 0xf2, 0xf7, 0x1f, 0x05, 0x39, - 0x43, 0xbb, 0x62, 0x44, 0xfe, 0x4b, 0x12, 0x72, 0xfc, 0xfd, 0x64, 0xd2, 0xaa, 0xe1, 0xff, 0x21, - 0xdf, 0x37, 0x2c, 0xdd, 0x16, 0x00, 0x58, 0x5c, 0x3b, 0xef, 0xfa, 0x0a, 0x97, 0xb9, 0xc3, 0x19, - 0x14, 0x87, 0x15, 0xbd, 0x0e, 0xb3, 0xae, 0xe9, 0x9e, 0xe0, 0xa7, 0x1c, 0x19, 0x52, 0x51, 0xc8, - 0xe0, 0x46, 0xf9, 0x1d, 0xfc, 0x94, 0x81, 0xc2, 0x15, 0x98, 0xf6, 0x4d, 0xe7, 0xdd, 0x9e, 0x92, - 0x97, 0x13, 0xad, 0xc2, 0x2c, 0x79, 0xfb, 0xf0, 0x1c, 0x60, 0xd0, 0xd8, 0x67, 0x07, 0x17, 0x55, - 0x32, 0xe4, 0x9c, 0x5c, 0xd4, 0xc9, 0x3b, 0xdc, 0x9a, 0x53, 0xcf, 0x61, 0xad, 0xc5, 0xdf, 0x6f, - 0xe8, 0x0c, 0x76, 0x9c, 0xea, 0x2e, 0xb8, 0x49, 0xc7, 0xe8, 0x9c, 0x17, 0x21, 0x4b, 0x4f, 0x0d, - 0xac, 0x5a, 0x8e, 0x66, 0x9f, 0xb2, 0xbb, 0x79, 0xda, 0x47, 0x53, 0xf8, 0xb0, 0xdc, 0x80, 0x0c, - 0x25, 0xa0, 0x45, 0x28, 0xb0, 0x73, 0x86, 0xde, 0xa0, 0x4b, 0xf5, 0x9b, 0x51, 0xf2, 0x94, 0xb0, - 0x3d, 0xe8, 0x22, 0x19, 0xd2, 0x3d, 0x43, 0x13, 0xf5, 0xd6, 0x0c, 0xd7, 0x43, 0x76, 0xdb, 0xd0, - 0x70, 0xb3, 0xae, 0xd0, 0x31, 0xb9, 0x01, 0xe5, 0x80, 0x5e, 0xc9, 0xeb, 0x56, 0x5f, 0x35, 0x6d, - 0x22, 0x72, 0x8f, 0xf7, 0xce, 0x33, 0x0a, 0x6d, 0xab, 0x6c, 0x53, 0x0a, 0x49, 0xcd, 0x7a, 0x4f, - 0xc3, 0x47, 0xe2, 0x48, 0x91, 0xde, 0xc8, 0x7f, 0x48, 0xc0, 0x2c, 0x17, 0x75, 0xb2, 0x57, 0xa6, - 0x67, 0xe3, 0x33, 0x2f, 0x40, 0xb9, 0xab, 0x1e, 0xb5, 0xe8, 0x11, 0x03, 0x6b, 0x80, 0xf2, 0xfe, - 0xe9, 0x74, 0x57, 0x3d, 0x72, 0xfb, 0x9d, 0xf2, 0xef, 0x12, 0x30, 0xe7, 0xdf, 0x16, 0x47, 0xc8, - 0x57, 0x00, 0xc4, 0xeb, 0xb9, 0xb3, 0xce, 0x2a, 0x5f, 0x67, 0x41, 0xf4, 0x94, 0xeb, 0x4a, 0x81, - 0x33, 0x35, 0xa3, 0x7b, 0xae, 0xc9, 0xd3, 0xe8, 0xb9, 0x4e, 0xd0, 0x80, 0xff, 0x63, 0xd2, 0xd9, - 0xce, 0x09, 0x5f, 0x08, 0x26, 0xdf, 0x7f, 0x4c, 0x98, 0x26, 0x8f, 0x1b, 0xa6, 0xa9, 0xf1, 0xc3, - 0x34, 0x1d, 0x17, 0xa6, 0xb7, 0x61, 0x7a, 0xd0, 0xef, 0x18, 0xaa, 0xd6, 0x32, 0xb1, 0x35, 0xe8, - 0xd8, 0xfc, 0xec, 0x49, 0x0e, 0xbb, 0x10, 0x51, 0xea, 0x83, 0x3e, 0x3f, 0x82, 0x19, 0x74, 0x6c, - 0xa5, 0x34, 0xf0, 0xdc, 0xc9, 0xdf, 0x71, 0xbb, 0xed, 0x21, 0xd6, 0xe1, 0x61, 0xfa, 0x22, 0xe4, - 0xe8, 0x29, 0xb1, 0x73, 0x54, 0x18, 0x8c, 0xd4, 0x2c, 0x19, 0x6e, 0x6a, 0xe8, 0x1a, 0xa4, 0x0f, - 0x55, 0xeb, 0x90, 0x7f, 0xd8, 0x54, 0x15, 0xc7, 0x63, 0xf4, 0x71, 0x0d, 0xd5, 0x3a, 0x54, 0xe8, - 0xb0, 0xfc, 0xef, 0x24, 0x94, 0x48, 0xc2, 0x13, 0x26, 0x40, 0x6b, 0xc1, 0x80, 0x2a, 0xae, 0x9d, - 0xf3, 0xec, 0xcf, 0xcd, 0x8d, 0x9e, 0xa8, 0x0a, 0x80, 0x40, 0x32, 0x1e, 0x04, 0x52, 0x1e, 0x10, - 0x08, 0x1f, 0x7e, 0x66, 0xc6, 0x38, 0xfc, 0x7c, 0x1b, 0xce, 0x39, 0x27, 0x80, 0x9e, 0x78, 0x24, - 0xa5, 0xfd, 0x18, 0xc1, 0x31, 0x2b, 0xe6, 0xba, 0x34, 0x2b, 0x9c, 0x4e, 0x73, 0xc7, 0x4e, 0xa7, - 0x31, 0xf9, 0x2f, 0x1f, 0x9b, 0xff, 0xea, 0xce, 0x11, 0x97, 0xff, 0x1d, 0x14, 0xfd, 0x2f, 0x54, - 0xad, 0x41, 0xbb, 0x8d, 0x2d, 0x6b, 0x7f, 0xd0, 0x69, 0x71, 0xa4, 0x67, 0xde, 0x50, 0x71, 0x07, - 0x76, 0x18, 0xc4, 0xff, 0x36, 0xe9, 0xf8, 0xd3, 0x96, 0xfa, 0x04, 0xb3, 0x2c, 0xf1, 0x5f, 0x8e, - 0xa9, 0xcf, 0x22, 0x0f, 0xc7, 0xe6, 0xd5, 0x4c, 0x6c, 0x5e, 0x65, 0x6d, 0xff, 0x90, 0x2a, 0x79, - 0x7d, 0xf8, 0x33, 0xf7, 0xe0, 0xf7, 0x34, 0xca, 0xf5, 0x67, 0xa2, 0x69, 0xf9, 0x53, 0xf7, 0x60, - 0x38, 0xaa, 0x7a, 0xff, 0x7c, 0xe6, 0xa6, 0x5f, 0xba, 0x9b, 0x3a, 0x95, 0xd7, 0x88, 0xc9, 0xb5, - 0x70, 0x13, 0x72, 0x2c, 0x0d, 0x88, 0xcd, 0xc7, 0xe4, 0x01, 0x47, 0xdd, 0x24, 0x0f, 0x88, 0x29, - 0xa1, 0x14, 0xe0, 0xe5, 0x7a, 0xb6, 0x29, 0x60, 0x09, 0x16, 0x23, 0x15, 0xc9, 0x5d, 0xfe, 0x93, - 0x04, 0x20, 0x3e, 0x7e, 0xa2, 0x7e, 0xd1, 0x84, 0xbe, 0xbe, 0x01, 0x65, 0xd6, 0x11, 0x6a, 0x8d, - 0xef, 0xf2, 0x33, 0x6c, 0x86, 0x53, 0x9c, 0x3a, 0x6d, 0xa1, 0x94, 0xa7, 0x2d, 0x24, 0x3f, 0x76, - 0x4a, 0x4f, 0x5f, 0x33, 0xe7, 0xba, 0xbf, 0x99, 0x13, 0x7e, 0xcc, 0x38, 0xdd, 0x1c, 0xb7, 0x42, - 0x76, 0xba, 0x39, 0xde, 0xa0, 0x4d, 0x8c, 0x1f, 0xb4, 0xbf, 0x48, 0x38, 0x1f, 0x1b, 0x04, 0x3e, - 0x31, 0xf9, 0x3c, 0xa8, 0x5e, 0xfe, 0x79, 0xca, 0xfd, 0xc4, 0x21, 0xf0, 0x31, 0xca, 0xe7, 0x13, - 0x70, 0xe2, 0x73, 0x49, 0x3a, 0xfe, 0x1d, 0xed, 0x32, 0x94, 0x22, 0xbe, 0x5c, 0x2b, 0x5a, 0x9e, - 0x03, 0xb9, 0x98, 0x34, 0x98, 0x3d, 0x6e, 0x1a, 0xcc, 0x45, 0xa4, 0xc1, 0x97, 0x21, 0xdd, 0xc3, - 0x47, 0xe2, 0x64, 0x73, 0x88, 0x15, 0x29, 0x9b, 0xfc, 0x3e, 0x94, 0x36, 0x54, 0xbb, 0x7d, 0x78, - 0x6c, 0x7f, 0xfb, 0x02, 0xe4, 0x4d, 0x36, 0x20, 0xa2, 0x49, 0xf2, 0x7c, 0xff, 0xe9, 0x11, 0x4d, - 0xc3, 0xc9, 0xe1, 0x95, 0xff, 0x0a, 0x50, 0x09, 0x0e, 0xa3, 0x3a, 0x4c, 0xf3, 0x63, 0x7c, 0xd6, - 0x6a, 0xe4, 0x41, 0xb4, 0x14, 0xfc, 0xa2, 0xd4, 0xf7, 0x15, 0x78, 0x63, 0x4a, 0x29, 0xed, 0x79, - 0xc8, 0xe8, 0x06, 0xf0, 0x93, 0xff, 0xd6, 0x01, 0x76, 0x3f, 0x39, 0x0f, 0x88, 0x70, 0xbb, 0xfd, - 0x8d, 0x29, 0xa5, 0xb0, 0x27, 0x68, 0x9e, 0x25, 0x68, 0x14, 0x1b, 0x39, 0xa2, 0x86, 0x96, 0xe0, - 0x4b, 0x41, 0xee, 0x12, 0x18, 0x19, 0x7d, 0xc9, 0xf9, 0x1e, 0xa1, 0xa3, 0x5b, 0xb6, 0xd3, 0xf3, - 0x89, 0xf8, 0x30, 0xd6, 0x95, 0xc0, 0x17, 0x4d, 0x88, 0xe8, 0x6b, 0x30, 0xcf, 0xe7, 0x5b, 0xd8, - 0x6e, 0xa9, 0xee, 0x77, 0x09, 0xbc, 0xfd, 0x73, 0x2d, 0x28, 0x2a, 0xf2, 0x53, 0x8a, 0xc6, 0x94, - 0x32, 0xb7, 0x17, 0x31, 0x8c, 0xd6, 0xa1, 0xc4, 0xbb, 0xe5, 0x7b, 0xa4, 0x48, 0xe0, 0x6d, 0xa0, - 0x0b, 0xc1, 0xd6, 0xb1, 0xf7, 0x75, 0xbd, 0x31, 0xa5, 0x14, 0x0d, 0x97, 0x4a, 0xf4, 0xc4, 0x45, - 0xb4, 0x69, 0x31, 0xcb, 0x0b, 0xe9, 0xa5, 0xa0, 0x0c, 0xdf, 0xcb, 0x24, 0xd1, 0x93, 0xe1, 0x21, - 0x13, 0x53, 0x71, 0x29, 0xc4, 0x54, 0xf9, 0xa0, 0xa9, 0x82, 0x07, 0x33, 0xc4, 0x54, 0x86, 0xa0, - 0x11, 0x25, 0xf3, 0xc9, 0x54, 0xc9, 0x85, 0xa0, 0x92, 0x43, 0x07, 0x1f, 0x44, 0xc9, 0x86, 0x43, - 0x44, 0xf7, 0x61, 0xd6, 0xab, 0x05, 0x61, 0x70, 0xa0, 0x72, 0xe4, 0x48, 0x65, 0x04, 0xad, 0x5e, - 0x35, 0x82, 0x63, 0xe8, 0x21, 0xcc, 0x71, 0xa9, 0xfb, 0x34, 0xc5, 0x0a, 0xb1, 0x45, 0x2a, 0xf6, - 0x4a, 0x50, 0x6c, 0x44, 0x41, 0xd3, 0x98, 0x52, 0x90, 0x11, 0x1a, 0x24, 0x1a, 0x17, 0x00, 0xc3, - 0xac, 0x56, 0x0a, 0x6a, 0x3c, 0xa2, 0xcb, 0x42, 0x34, 0x6e, 0x79, 0xc8, 0xe8, 0x36, 0xcc, 0x08, - 0x29, 0xdc, 0x70, 0xec, 0x0c, 0xff, 0x62, 0x48, 0x4c, 0xd0, 0x72, 0xe2, 0xe9, 0xdc, 0x74, 0xf7, - 0x61, 0x56, 0x08, 0xea, 0xaa, 0x4f, 0x30, 0x87, 0x49, 0x7a, 0x8a, 0x1f, 0x55, 0x1e, 0x85, 0xde, - 0x55, 0x88, 0xf6, 0xac, 0xe0, 0x18, 0xd1, 0x9e, 0x6f, 0x93, 0x42, 0x7b, 0xe5, 0xa0, 0xf6, 0x62, - 0x2b, 0x73, 0xa2, 0x3d, 0x2b, 0x34, 0x88, 0x1e, 0xc3, 0x39, 0x21, 0xd8, 0x6f, 0x97, 0x0a, 0x95, - 0x7c, 0x35, 0x24, 0x39, 0xda, 0x30, 0x62, 0xcf, 0x3e, 0xcb, 0xac, 0xbb, 0xd0, 0x4f, 0x3d, 0xb1, - 0x1a, 0x0c, 0xa7, 0x70, 0x4d, 0x45, 0xc2, 0xc9, 0x72, 0xa9, 0x68, 0x0b, 0x2a, 0x42, 0x84, 0xc6, - 0x73, 0x68, 0x0d, 0x05, 0x0f, 0xb0, 0xa2, 0x6b, 0x84, 0xc6, 0x94, 0x52, 0xb6, 0xfc, 0x23, 0x1b, - 0x05, 0xc8, 0xf1, 0x51, 0xf9, 0x2d, 0x98, 0xe6, 0x38, 0xcb, 0x53, 0xf2, 0x17, 0xa1, 0x60, 0xf2, - 0x6b, 0x01, 0xd9, 0x8b, 0x21, 0xc8, 0x66, 0xe3, 0x14, 0xb3, 0x5d, 0x6e, 0xf9, 0x9f, 0x00, 0xd5, - 0x10, 0x03, 0xda, 0x8c, 0x46, 0xed, 0x8b, 0x71, 0xa8, 0xcd, 0xa6, 0x86, 0x60, 0xfb, 0x66, 0x04, - 0x6c, 0x2f, 0x46, 0xc2, 0xb6, 0x23, 0xc0, 0x83, 0xdb, 0x9b, 0xd1, 0xb8, 0x7d, 0x31, 0x0e, 0xb7, - 0x83, 0x8b, 0xe0, 0xa6, 0x7c, 0x23, 0x0a, 0xb8, 0x2f, 0x44, 0x03, 0xb7, 0x23, 0xc2, 0x8b, 0xdc, - 0x5f, 0x1f, 0x81, 0xdc, 0x2f, 0x8c, 0x42, 0x6e, 0x47, 0x6a, 0x34, 0x74, 0x6f, 0x44, 0x42, 0xf7, - 0x52, 0x0c, 0x74, 0x3b, 0xc2, 0x7c, 0xd8, 0xbd, 0x19, 0x8d, 0xdd, 0x17, 0xe3, 0xb0, 0xdb, 0xd5, - 0x95, 0x0f, 0xbc, 0x6f, 0x46, 0x80, 0xf7, 0x62, 0x24, 0x78, 0xbb, 0x06, 0x73, 0xd1, 0xfb, 0x8d, - 0x28, 0xf4, 0xbe, 0x10, 0x8d, 0xde, 0xae, 0xa6, 0x3d, 0xf0, 0xfd, 0x60, 0x18, 0x7c, 0x5f, 0x19, - 0x0a, 0xdf, 0x8e, 0xbc, 0x08, 0xfc, 0x7e, 0x34, 0x14, 0xbf, 0xaf, 0x0e, 0xc7, 0x6f, 0x47, 0x70, - 0x14, 0x80, 0x6f, 0x46, 0x03, 0xf8, 0xc5, 0x38, 0x00, 0x77, 0xd5, 0xee, 0x43, 0xf0, 0x46, 0x0c, - 0x82, 0x2f, 0xc7, 0x22, 0xb8, 0x23, 0x28, 0x00, 0xe1, 0x0f, 0x86, 0x41, 0xf8, 0x95, 0xa1, 0x10, - 0xee, 0x6a, 0x30, 0x8c, 0xe1, 0x8f, 0x86, 0x62, 0xf8, 0xd5, 0xe1, 0x18, 0xee, 0x6a, 0x30, 0x02, - 0xc4, 0xbf, 0x3a, 0x1c, 0xc4, 0xaf, 0x8d, 0x00, 0x71, 0x47, 0x76, 0x24, 0x8a, 0x6f, 0x44, 0xa2, - 0xf8, 0x52, 0x0c, 0x8a, 0xbb, 0x91, 0xe5, 0x85, 0xf1, 0xed, 0x58, 0x18, 0xbf, 0x3c, 0x04, 0xc6, - 0x1d, 0x59, 0x21, 0x1c, 0x07, 0xc8, 0x8b, 0xe1, 0xb5, 0x7f, 0x54, 0x21, 0xbf, 0xc5, 0x65, 0xa0, - 0x2d, 0x28, 0x31, 0xd8, 0xe4, 0xff, 0xcb, 0x0e, 0x2f, 0x91, 0xa5, 0x11, 0x58, 0x8c, 0xea, 0x50, - 0xb8, 0x8d, 0x6d, 0x2e, 0x6b, 0x48, 0xad, 0x2c, 0x0d, 0x03, 0x64, 0xb2, 0x28, 0xa6, 0xcb, 0xb8, - 0x45, 0xf9, 0xb2, 0xa9, 0x34, 0x02, 0x9b, 0x51, 0x03, 0x8a, 0x44, 0xa9, 0x6c, 0xcc, 0x42, 0xc3, - 0xca, 0x67, 0x69, 0x28, 0x44, 0x23, 0x0c, 0x73, 0xbb, 0x62, 0x7b, 0x5e, 0x30, 0x1d, 0xaf, 0x8c, - 0x96, 0xc6, 0xc4, 0x6c, 0xf4, 0x16, 0x14, 0xa9, 0xb7, 0xf2, 0x6f, 0x75, 0x87, 0xd6, 0xd3, 0xd2, - 0x70, 0xc8, 0xa6, 0x06, 0xa6, 0x51, 0xca, 0x85, 0x0d, 0x2f, 0xac, 0xa5, 0x11, 0xd8, 0xcd, 0x0d, - 0xcc, 0x65, 0x0d, 0xa9, 0xb0, 0xa5, 0x61, 0x00, 0x2e, 0x2c, 0xc2, 0x06, 0x7c, 0x16, 0x09, 0xd5, - 0xda, 0xd2, 0x50, 0x28, 0x47, 0xef, 0x42, 0xd5, 0x13, 0xd8, 0x7c, 0x5d, 0x63, 0xd4, 0xdc, 0xd2, - 0x38, 0xc0, 0x8e, 0x5a, 0x80, 0xbc, 0xa1, 0xcd, 0xc5, 0x8f, 0x53, 0x7b, 0x4b, 0x63, 0x01, 0x3c, - 0xb1, 0x0e, 0x7d, 0xae, 0x38, 0xce, 0x1e, 0x5e, 0x84, 0x4b, 0x23, 0x20, 0x1e, 0xed, 0xc0, 0x34, - 0xb3, 0x97, 0x90, 0x37, 0xa2, 0x1a, 0x97, 0x46, 0x61, 0x3d, 0xd1, 0xaf, 0x8b, 0xc8, 0x42, 0xea, - 0x18, 0x55, 0xb9, 0x34, 0x0e, 0xec, 0x13, 0xfd, 0x7a, 0xd4, 0x2e, 0xc4, 0x8f, 0x53, 0x9d, 0x4b, - 0x63, 0xc1, 0x3f, 0xda, 0x83, 0x59, 0xaf, 0xde, 0xc5, 0x13, 0xc6, 0xaa, 0xd2, 0xa5, 0xf1, 0xd2, - 0x00, 0xba, 0x03, 0x25, 0xef, 0x3f, 0x12, 0x68, 0x68, 0xbd, 0x2e, 0x0d, 0xcf, 0x03, 0xe8, 0x1d, - 0x28, 0x0b, 0xd0, 0x16, 0x8b, 0x1d, 0x59, 0xb8, 0x4b, 0xa3, 0x73, 0x02, 0x7a, 0x0d, 0x32, 0xb4, - 0xe0, 0x46, 0xf3, 0xd1, 0x5d, 0x15, 0x69, 0x21, 0xa6, 0x74, 0x47, 0x0f, 0xa1, 0xc2, 0x40, 0x9e, - 0x8b, 0xbe, 0xd7, 0xd1, 0x22, 0x96, 0x14, 0xf8, 0x83, 0x34, 0x62, 0x49, 0xa1, 0x3f, 0x22, 0xbf, - 0x02, 0x15, 0x9f, 0xb3, 0x12, 0xda, 0xe5, 0xe1, 0xfe, 0x4a, 0x24, 0xcb, 0x23, 0x5c, 0x96, 0x88, - 0xd9, 0x85, 0x19, 0xcf, 0x4f, 0x57, 0x84, 0x12, 0x76, 0x74, 0xff, 0xef, 0x61, 0xd2, 0xa5, 0x18, - 0x06, 0x57, 0x68, 0x0b, 0x50, 0xc0, 0x34, 0x84, 0x7a, 0x65, 0x94, 0x75, 0x88, 0xf0, 0xab, 0x23, - 0x0d, 0xc4, 0x15, 0xe2, 0x73, 0xd3, 0x68, 0x85, 0x04, 0xff, 0xfe, 0x8a, 0x50, 0x48, 0xf8, 0x6f, - 0xac, 0x77, 0xa0, 0xec, 0xf5, 0xd1, 0x80, 0x0d, 0xa3, 0xff, 0x91, 0xf2, 0xda, 0x30, 0xee, 0xb7, - 0xa1, 0x77, 0xa1, 0xea, 0xcf, 0x61, 0x84, 0xe8, 0x5b, 0x50, 0xf4, 0x9f, 0x39, 0x7e, 0x78, 0x88, - 0xf9, 0x61, 0x86, 0xe4, 0x41, 0xcf, 0x9f, 0x2e, 0xde, 0xc0, 0x0a, 0xff, 0x47, 0xe3, 0x0d, 0xac, - 0x88, 0xdf, 0x63, 0x36, 0xd2, 0x8f, 0x93, 0xfd, 0xbd, 0xbd, 0x2c, 0x3d, 0x97, 0x7d, 0xf5, 0x3f, - 0x01, 0x00, 0x00, 0xff, 0xff, 0x48, 0x9e, 0xe0, 0x05, 0xd0, 0x44, 0x00, 0x00, + // 3712 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5b, 0x5d, 0x6c, 0x1c, 0x57, + 0xf5, 0xf7, 0xec, 0xf7, 0x9e, 0x5d, 0x7b, 0xd7, 0xd7, 0x8e, 0xbd, 0x19, 0xc7, 0x71, 0x32, 0x49, + 0x5a, 0xff, 0xf5, 0x6f, 0x9d, 0xca, 0x05, 0x54, 0x94, 0x94, 0x62, 0x67, 0xdd, 0x78, 0x9b, 0xd8, + 0x71, 0xc7, 0x49, 0x13, 0x42, 0x61, 0x35, 0xde, 0xb9, 0xb6, 0x87, 0xec, 0xee, 0x2c, 0x33, 0xb3, + 0xad, 0x53, 0x9e, 0x90, 0x2a, 0x21, 0x84, 0x84, 0x2a, 0x9e, 0x11, 0x4f, 0x7d, 0xe3, 0x09, 0xde, + 0x90, 0x80, 0x57, 0x40, 0x42, 0x45, 0xaa, 0x10, 0x0f, 0x3c, 0x14, 0x9e, 0x78, 0x83, 0x17, 0xde, + 0x40, 0x48, 0xe8, 0x7e, 0xcd, 0xf7, 0xec, 0x87, 0x3f, 0x12, 0xfa, 0x36, 0x73, 0xee, 0xb9, 0x67, + 0xee, 0x3d, 0x1f, 0xbf, 0x73, 0xe6, 0xdc, 0x19, 0x98, 0xea, 0x60, 0x47, 0x33, 0xba, 0xfb, 0xe6, + 0x4a, 0xcf, 0x32, 0x1d, 0x13, 0x15, 0xc4, 0xbd, 0x5c, 0xc5, 0xdd, 0x96, 0xf5, 0xb4, 0xe7, 0x18, + 0x66, 0x97, 0x8d, 0xc9, 0x70, 0x60, 0x1e, 0x70, 0x3e, 0x79, 0xe9, 0xc0, 0x34, 0x0f, 0xda, 0xf8, + 0x3a, 0xbd, 0xdb, 0xeb, 0xef, 0x5f, 0x77, 0x8c, 0x0e, 0xb6, 0x1d, 0xad, 0xd3, 0x13, 0xcc, 0x5d, + 0x53, 0xc7, 0xfc, 0xba, 0xd2, 0x33, 0x8d, 0xae, 0x83, 0x2d, 0x7d, 0x8f, 0x13, 0xca, 0xa6, 0xa5, + 0x63, 0xcb, 0x66, 0x77, 0xca, 0x32, 0x4c, 0xaa, 0xf8, 0xdb, 0x7d, 0x6c, 0x3b, 0x9b, 0x58, 0xd3, + 0xb1, 0x85, 0xe6, 0x21, 0xaf, 0xf5, 0x8c, 0xe6, 0x13, 0xfc, 0xb4, 0x26, 0x5d, 0x92, 0x96, 0xcb, + 0x6a, 0x4e, 0xeb, 0x19, 0x77, 0xf0, 0x53, 0xe5, 0xa7, 0x69, 0xc8, 0xad, 0xf7, 0x5b, 0x4f, 0xb0, + 0x83, 0x10, 0x64, 0xba, 0x5a, 0x07, 0x73, 0x06, 0x7a, 0x8d, 0x5e, 0x83, 0x52, 0x4f, 0x73, 0x0e, + 0x9b, 0x2d, 0xa3, 0x77, 0x88, 0xad, 0x5a, 0xea, 0x92, 0xb4, 0x3c, 0xb5, 0x3a, 0xbf, 0xe2, 0xdb, + 0xc8, 0x2d, 0x3a, 0xb2, 0xdb, 0x37, 0x1c, 0xac, 0x02, 0xe1, 0x65, 0x04, 0x74, 0x0b, 0xa0, 0x65, + 0x61, 0xcd, 0xc1, 0x7a, 0x53, 0x73, 0x6a, 0xe9, 0x4b, 0xd2, 0x72, 0x69, 0x55, 0x5e, 0x61, 0x7b, + 0x5c, 0x11, 0x7b, 0x5c, 0xb9, 0x2f, 0xf6, 0xb8, 0x5e, 0xf8, 0xed, 0x67, 0x4b, 0x13, 0x1f, 0xfd, + 0x65, 0x49, 0x52, 0x8b, 0x7c, 0xde, 0x9a, 0x83, 0x5e, 0x81, 0x59, 0x1d, 0xef, 0x6b, 0xfd, 0xb6, + 0xd3, 0xb4, 0xf1, 0x41, 0x07, 0x77, 0x9d, 0xa6, 0x6d, 0x7c, 0x80, 0x6b, 0x99, 0x4b, 0xd2, 0x72, + 0x5a, 0x45, 0x7c, 0x6c, 0x97, 0x0d, 0xed, 0x1a, 0x1f, 0x60, 0xf4, 0x10, 0xce, 0x8b, 0x19, 0x16, + 0xd6, 0xfb, 0x5d, 0x5d, 0xeb, 0xb6, 0x9e, 0x36, 0xed, 0xd6, 0x21, 0xee, 0xe0, 0x5a, 0x96, 0xae, + 0x62, 0x61, 0xc5, 0x53, 0x9e, 0xea, 0xf2, 0xec, 0x52, 0x16, 0x75, 0x9e, 0xcf, 0x0e, 0x0f, 0x20, + 0x1d, 0x16, 0x85, 0x60, 0x6f, 0xf7, 0xcd, 0x9e, 0x66, 0x69, 0x1d, 0xec, 0x60, 0xcb, 0xae, 0xe5, + 0xa8, 0xf0, 0x4b, 0x7e, 0xdd, 0x6c, 0xb8, 0x97, 0x3b, 0x2e, 0x9f, 0xba, 0xc0, 0xc5, 0xc4, 0x0d, + 0xa2, 0x45, 0x80, 0x9e, 0x66, 0x39, 0x5d, 0x6c, 0x35, 0x0d, 0xbd, 0x96, 0xa7, 0x96, 0x28, 0x72, + 0x4a, 0x43, 0x57, 0x0c, 0x98, 0x62, 0xc6, 0xba, 0x6b, 0xd8, 0x4e, 0xc3, 0xc1, 0x9d, 0x58, 0xa3, + 0x05, 0x55, 0x9f, 0x3a, 0x96, 0xea, 0x95, 0x8f, 0xd3, 0x30, 0xc3, 0x9e, 0x75, 0x8b, 0xd2, 0xb8, + 0x3f, 0xa1, 0xeb, 0x90, 0x3b, 0xa4, 0x3e, 0x55, 0xab, 0x50, 0xc1, 0xf3, 0x2b, 0xae, 0xbf, 0x07, + 0x5c, 0x4e, 0xe5, 0x6c, 0xa7, 0xec, 0x56, 0x49, 0x1e, 0x91, 0x3e, 0x9e, 0x47, 0x64, 0xce, 0xd2, + 0x23, 0xb2, 0xa7, 0xef, 0x11, 0xb9, 0xb0, 0x47, 0x7c, 0x15, 0x66, 0x83, 0x56, 0xb2, 0x7b, 0x66, + 0xd7, 0xc6, 0x68, 0x19, 0x72, 0x7b, 0x94, 0x4e, 0xf5, 0x5e, 0x5a, 0xad, 0x7a, 0x66, 0x62, 0xfc, + 0x2a, 0x1f, 0x57, 0x1e, 0x42, 0x95, 0x51, 0x6e, 0x63, 0xe7, 0x34, 0x8d, 0xac, 0xbc, 0x0e, 0xd3, + 0x3e, 0xc1, 0x63, 0xaf, 0xeb, 0xb1, 0xf0, 0xbf, 0x3a, 0x6e, 0xe3, 0xd3, 0xf5, 0x3f, 0x65, 0x4e, + 0x68, 0x4d, 0xc8, 0x66, 0xab, 0x53, 0x3e, 0x92, 0xc4, 0x9a, 0x49, 0x80, 0x1d, 0xfb, 0x91, 0x73, + 0x90, 0x6b, 0xf5, 0x2d, 0xdb, 0xb4, 0x04, 0xd8, 0xb2, 0x3b, 0x34, 0x0b, 0xd9, 0xb6, 0xd1, 0x31, + 0x58, 0x4c, 0x66, 0x55, 0x76, 0x83, 0x2e, 0x40, 0x51, 0x37, 0x2c, 0xdc, 0x22, 0x86, 0xa7, 0x7e, + 0x9c, 0x55, 0x3d, 0x82, 0xf2, 0x08, 0x90, 0x7f, 0x45, 0x5c, 0x8d, 0x2b, 0x90, 0x35, 0x1c, 0xdc, + 0xb1, 0x6b, 0xd2, 0xa5, 0xf4, 0x72, 0x69, 0xb5, 0x16, 0xd6, 0xa2, 0xc0, 0x07, 0x95, 0xb1, 0x11, + 0x25, 0x74, 0x4c, 0x0b, 0xd3, 0x07, 0x17, 0x54, 0x7a, 0xad, 0x7c, 0x57, 0x82, 0x05, 0xc6, 0xbd, + 0x8b, 0x9d, 0x35, 0xc7, 0xb1, 0x8c, 0xbd, 0x3e, 0x79, 0xe4, 0xa9, 0x46, 0x7a, 0xd0, 0x7d, 0x53, + 0x61, 0xf7, 0xbd, 0x08, 0x17, 0xe2, 0x97, 0xc0, 0x0d, 0xf2, 0xa1, 0x04, 0x33, 0x6b, 0xba, 0x6e, + 0x61, 0xdb, 0xc6, 0xfa, 0x3d, 0x92, 0xe2, 0xee, 0x52, 0x9d, 0x2d, 0x0b, 0x4d, 0x32, 0x2f, 0x42, + 0x2b, 0x3c, 0xfd, 0x79, 0x2c, 0x42, 0xbb, 0xb7, 0x60, 0xd6, 0x76, 0x4c, 0x4b, 0x3b, 0xc0, 0x4d, + 0x92, 0x3f, 0x9b, 0x1a, 0x93, 0xc6, 0x61, 0x71, 0x7a, 0x85, 0x26, 0xd5, 0x6d, 0x53, 0xc7, 0xfc, + 0x31, 0x2a, 0xe2, 0xec, 0x3e, 0x9a, 0xf2, 0x87, 0x14, 0xcc, 0x71, 0x4c, 0x79, 0x68, 0x19, 0xae, + 0x33, 0xde, 0x6b, 0xeb, 0xc7, 0x72, 0x0e, 0x5f, 0x04, 0x94, 0x85, 0xbf, 0x13, 0xed, 0x11, 0x9c, + 0xe3, 0x3a, 0xa2, 0xd7, 0xa8, 0x06, 0x79, 0x8e, 0x72, 0x1c, 0xe0, 0xc4, 0x2d, 0xba, 0x01, 0xe0, + 0xa1, 0xd9, 0x28, 0x30, 0xe6, 0x63, 0x47, 0x37, 0x40, 0xee, 0x68, 0x47, 0x02, 0xb5, 0xb0, 0x1e, + 0x84, 0xd2, 0x2c, 0x7d, 0xd2, 0x7c, 0x47, 0x3b, 0xda, 0x10, 0x0c, 0x7e, 0x3c, 0xad, 0x03, 0xe0, + 0xa3, 0x9e, 0x61, 0x69, 0xd4, 0x5f, 0x73, 0x63, 0x64, 0x17, 0xdf, 0x3c, 0xe5, 0x53, 0x09, 0xe6, + 0x83, 0x1a, 0x65, 0x16, 0x27, 0x2a, 0xdd, 0x84, 0xaa, 0x26, 0x6c, 0xde, 0xa4, 0x56, 0x14, 0x7e, + 0xbe, 0xe8, 0x29, 0x37, 0xc6, 0x2b, 0xd4, 0x8a, 0x3b, 0x8d, 0xde, 0xdb, 0xe8, 0x55, 0x98, 0xb4, + 0x4c, 0xd3, 0x69, 0xf6, 0x0c, 0xdc, 0xc2, 0xae, 0x03, 0xae, 0x57, 0xc8, 0x92, 0xfe, 0xfc, 0xd9, + 0x52, 0x7e, 0x87, 0xd0, 0x1b, 0x75, 0xb5, 0x44, 0xb8, 0xd8, 0x8d, 0x4e, 0x93, 0x93, 0x65, 0xbc, + 0xa7, 0x39, 0x98, 0xd6, 0x4b, 0x69, 0x3a, 0x65, 0x9e, 0x4f, 0xa9, 0x50, 0xae, 0x1d, 0x36, 0x7e, + 0x07, 0x3f, 0x55, 0xa1, 0xe7, 0x5e, 0x2b, 0xff, 0xf6, 0x36, 0x75, 0xcb, 0xec, 0x90, 0x15, 0x3d, + 0x77, 0x3f, 0x79, 0x09, 0xf2, 0xdc, 0x29, 0xb8, 0x93, 0x20, 0x9f, 0x93, 0xec, 0xb0, 0x2b, 0x55, + 0xb0, 0xa0, 0x1b, 0x50, 0x31, 0x2d, 0xe3, 0xc0, 0xe8, 0x6a, 0x6d, 0xa1, 0xf8, 0x2c, 0x55, 0x7c, + 0x5c, 0x80, 0x4d, 0x09, 0x56, 0xa6, 0x6c, 0x65, 0x13, 0x6a, 0xa1, 0xcd, 0x7b, 0x26, 0xf5, 0x2d, + 0x43, 0x1a, 0xba, 0x0c, 0xe5, 0x47, 0x12, 0x9c, 0xe7, 0xa2, 0xea, 0xe6, 0xfb, 0xdd, 0xb6, 0xa9, + 0xe9, 0xcf, 0x5d, 0x93, 0xca, 0x27, 0x12, 0xc8, 0x91, 0x45, 0x9d, 0x85, 0xd3, 0xfa, 0x74, 0x95, + 0x1a, 0x6e, 0xb2, 0xe3, 0x7b, 0xeb, 0x0f, 0x25, 0x38, 0xc7, 0x37, 0xd4, 0xe8, 0xee, 0x9b, 0xcf, + 0x5f, 0xc3, 0x6f, 0xba, 0x20, 0xcb, 0xd6, 0x13, 0xeb, 0x3e, 0xc3, 0x55, 0x42, 0xb2, 0xb8, 0x08, + 0xc3, 0x40, 0xed, 0xf0, 0x1c, 0xb7, 0xf6, 0x13, 0xc9, 0x0d, 0x8e, 0x60, 0xc9, 0x71, 0xba, 0xae, + 0x13, 0x72, 0x86, 0xd4, 0xe8, 0xce, 0xf0, 0x51, 0x0a, 0xe6, 0x48, 0xd1, 0xc0, 0x17, 0x69, 0x9f, + 0x85, 0xca, 0xe6, 0x20, 0xd7, 0xb3, 0xf0, 0xbe, 0x71, 0xc4, 0x95, 0xc6, 0xef, 0xd0, 0x12, 0x94, + 0x6c, 0x47, 0xb3, 0x9c, 0xa6, 0xb6, 0x4f, 0x2c, 0x4c, 0x5d, 0x58, 0x05, 0x4a, 0x5a, 0x23, 0x14, + 0x74, 0x19, 0x00, 0x77, 0xf5, 0xe6, 0x1e, 0xde, 0x27, 0x35, 0x4c, 0x86, 0xee, 0x2a, 0x55, 0x93, + 0xd4, 0x22, 0xee, 0xea, 0xeb, 0x94, 0x48, 0x8a, 0x28, 0x0b, 0x93, 0x32, 0xcb, 0x78, 0x8f, 0x65, + 0xb0, 0x82, 0xea, 0x11, 0xbc, 0xc2, 0x2b, 0xe7, 0x2f, 0xbc, 0x16, 0x01, 0xc8, 0x4e, 0x9a, 0xfb, + 0x6d, 0xed, 0xc0, 0xa6, 0x2f, 0x5b, 0x79, 0xb5, 0x48, 0x28, 0x6f, 0x12, 0x02, 0x4d, 0x51, 0x41, + 0x95, 0x78, 0x26, 0xbb, 0x19, 0xac, 0xbf, 0x5e, 0xf0, 0x54, 0x92, 0x30, 0x63, 0x65, 0x48, 0x35, + 0x26, 0x63, 0xc8, 0x88, 0x17, 0x3a, 0xea, 0x57, 0x92, 0xcf, 0xaf, 0xc6, 0x43, 0x84, 0x05, 0x28, + 0x1a, 0x76, 0x93, 0x6b, 0x3a, 0x4d, 0x1f, 0x51, 0x30, 0xec, 0x1d, 0x7a, 0xaf, 0xfc, 0x80, 0x3a, + 0x62, 0x4c, 0xb9, 0x77, 0x2c, 0x4b, 0x2f, 0x41, 0x89, 0xd9, 0xb6, 0xe9, 0x2b, 0xfc, 0x80, 0x91, + 0xb6, 0x47, 0x28, 0xff, 0x16, 0x08, 0xce, 0xc7, 0x15, 0x7e, 0xf7, 0xda, 0xba, 0xb2, 0x01, 0x68, + 0xc7, 0x32, 0xbf, 0x85, 0x5b, 0x7e, 0x78, 0x1a, 0x7b, 0x8d, 0xca, 0x6b, 0x30, 0x13, 0x10, 0xc3, + 0x2b, 0xe8, 0xcb, 0x50, 0xee, 0x31, 0x72, 0xd3, 0xd6, 0xda, 0xc2, 0x55, 0x4b, 0x9c, 0xb6, 0xab, + 0xb5, 0x1d, 0xe5, 0xfb, 0x79, 0xc8, 0xdd, 0xdb, 0x23, 0xb7, 0x89, 0x2e, 0x7d, 0x0d, 0xa6, 0xbc, + 0x2a, 0xca, 0x87, 0x07, 0x93, 0x2e, 0x75, 0x87, 0x03, 0xc3, 0x7b, 0xd8, 0xb2, 0xbd, 0x02, 0x5f, + 0xdc, 0x92, 0xed, 0xd8, 0x8e, 0xe6, 0xf4, 0x6d, 0xea, 0xd6, 0x53, 0xfe, 0xed, 0xb0, 0x47, 0xaf, + 0xec, 0xd2, 0x61, 0x95, 0xb3, 0xa1, 0x97, 0xa1, 0x68, 0x3b, 0x16, 0xd6, 0x3a, 0x44, 0xa1, 0x59, + 0x1a, 0x0a, 0x55, 0x1e, 0xe0, 0x85, 0x5d, 0x3a, 0xd0, 0xa8, 0xab, 0x05, 0xc6, 0xd2, 0xd0, 0x43, + 0xbd, 0x80, 0xdc, 0xf1, 0xda, 0x30, 0x6b, 0xe4, 0x99, 0xe4, 0xe9, 0x44, 0x46, 0x7e, 0x0c, 0x19, + 0x05, 0x36, 0x6d, 0x8d, 0x94, 0xe1, 0xac, 0xfa, 0xc3, 0x54, 0x46, 0x61, 0x9c, 0x75, 0xf0, 0x79, + 0x6b, 0x0e, 0xba, 0x0d, 0x35, 0x4f, 0xdb, 0x44, 0x4f, 0xba, 0xe6, 0x68, 0xcd, 0xae, 0xd9, 0x6d, + 0xe1, 0x5a, 0x91, 0xaa, 0x62, 0x92, 0xab, 0x22, 0xbb, 0x4d, 0x88, 0xea, 0x9c, 0xcb, 0xbe, 0xc5, + 0xb9, 0x29, 0x1d, 0xbd, 0x0c, 0x28, 0x2a, 0xa8, 0x06, 0xd4, 0x74, 0xd3, 0x91, 0x39, 0xe8, 0x25, + 0x40, 0xfb, 0xc6, 0x51, 0xb8, 0x4e, 0x2e, 0x51, 0x88, 0xaf, 0xd2, 0x11, 0x7f, 0x81, 0xbc, 0x09, + 0xd3, 0xd1, 0x46, 0x43, 0x79, 0x78, 0x85, 0x5e, 0xb5, 0xc2, 0x1d, 0x86, 0x07, 0x70, 0x2e, 0xbe, + 0xb3, 0x30, 0x39, 0x62, 0x67, 0x61, 0x16, 0x27, 0xb4, 0x14, 0x1c, 0xd3, 0xd1, 0xda, 0x6c, 0x1b, + 0x53, 0x74, 0x1b, 0x45, 0x4a, 0xa1, 0xeb, 0x5f, 0x82, 0x92, 0xd1, 0x6d, 0x1b, 0x5d, 0xcc, 0xc6, + 0x2b, 0x74, 0x1c, 0x18, 0x49, 0x30, 0x58, 0xb8, 0x63, 0x3a, 0x9c, 0xa1, 0xca, 0x18, 0x18, 0x89, + 0x30, 0x28, 0x6f, 0x43, 0x8e, 0x79, 0x2d, 0x2a, 0x41, 0xbe, 0xb1, 0xfd, 0xce, 0xda, 0xdd, 0x46, + 0xbd, 0x3a, 0x81, 0x26, 0xa1, 0xf8, 0x60, 0xe7, 0xee, 0xbd, 0xb5, 0x7a, 0x63, 0xfb, 0x76, 0x55, + 0x42, 0x53, 0x00, 0xb7, 0xee, 0x6d, 0x6d, 0x35, 0xee, 0xdf, 0x27, 0xf7, 0x29, 0x32, 0xcc, 0xef, + 0x37, 0xea, 0xd5, 0x34, 0x2a, 0x43, 0xa1, 0xbe, 0x71, 0x77, 0x83, 0x0e, 0x66, 0x94, 0x0f, 0xd3, + 0x80, 0x58, 0x40, 0xac, 0xe3, 0x03, 0xa3, 0x7b, 0x92, 0x57, 0xf3, 0xb3, 0x09, 0xe4, 0xa0, 0x83, + 0x67, 0x8e, 0xe7, 0xe0, 0xb1, 0xae, 0x93, 0x3f, 0x55, 0xd7, 0x29, 0x9c, 0xc4, 0x75, 0x94, 0x5f, + 0xa7, 0x60, 0x26, 0x60, 0x06, 0x8e, 0xa6, 0x67, 0xa6, 0xd6, 0x00, 0xdc, 0x65, 0x86, 0xc2, 0x5d, + 0xac, 0x02, 0xb3, 0xa7, 0xaa, 0xc0, 0xdc, 0x89, 0x14, 0xf8, 0x77, 0x49, 0x28, 0x30, 0xf0, 0x86, + 0x38, 0xbe, 0x23, 0x07, 0x14, 0x23, 0x0d, 0x55, 0xcc, 0x20, 0xe8, 0x4c, 0x9d, 0x1c, 0x3a, 0xd3, + 0x09, 0xd0, 0xa9, 0xcc, 0xc1, 0x6c, 0x70, 0xbb, 0xbc, 0xb1, 0xf3, 0x63, 0x09, 0xaa, 0x6c, 0xe0, + 0x24, 0x6d, 0xc7, 0xb3, 0x72, 0x3b, 0xe5, 0x75, 0x98, 0xf6, 0xad, 0xce, 0xeb, 0x5d, 0x9a, 0x94, + 0x18, 0xed, 0x5d, 0x32, 0x66, 0x95, 0x8f, 0x2b, 0x3f, 0x4b, 0x89, 0xf9, 0x27, 0xed, 0x23, 0xc6, + 0x6e, 0xef, 0xff, 0xa0, 0xea, 0xdb, 0x9e, 0xbf, 0xa4, 0xae, 0x78, 0x1b, 0x64, 0xb5, 0x75, 0x80, + 0x95, 0x37, 0x25, 0xd3, 0x21, 0xd6, 0x5b, 0xac, 0x3b, 0x19, 0x28, 0xa1, 0x33, 0x89, 0x25, 0x74, + 0xd6, 0x5f, 0x42, 0x37, 0xa0, 0xc2, 0xb6, 0xdc, 0x34, 0xba, 0xad, 0x76, 0x5f, 0xc7, 0x5e, 0x7c, + 0x84, 0x74, 0x23, 0x3a, 0x92, 0x0d, 0xce, 0xa7, 0x4e, 0xb1, 0x89, 0xe2, 0x5e, 0x79, 0x24, 0x00, + 0x7e, 0xc4, 0x46, 0x67, 0x50, 0xec, 0xa0, 0x46, 0xe7, 0x6f, 0xd2, 0x30, 0x15, 0xe4, 0x8e, 0x71, + 0x10, 0x69, 0x88, 0x83, 0xa4, 0x92, 0xea, 0xb6, 0xf4, 0x68, 0x75, 0x5b, 0xb0, 0x10, 0xcb, 0x9c, + 0x42, 0x21, 0x96, 0x3d, 0x85, 0x42, 0x2c, 0x77, 0xfa, 0x85, 0x58, 0xfe, 0xe4, 0x68, 0x52, 0x48, + 0x42, 0x93, 0x2f, 0xc0, 0x5c, 0xbc, 0x37, 0x21, 0x19, 0x0a, 0xee, 0x74, 0x89, 0xbd, 0xf3, 0x88, + 0x7b, 0xe5, 0x63, 0x09, 0x6a, 0xbe, 0xa4, 0x75, 0xc2, 0xf3, 0x84, 0x33, 0xc3, 0x9c, 0xb7, 0xe0, + 0x7c, 0xcc, 0x2a, 0x79, 0x1c, 0x8c, 0x07, 0xf7, 0xca, 0x77, 0x84, 0xac, 0x37, 0x8d, 0xae, 0x61, + 0x1f, 0x9e, 0x70, 0xcb, 0x63, 0x3e, 0xfc, 0x02, 0xc8, 0x71, 0x0f, 0xe7, 0xc8, 0xff, 0x8f, 0x14, + 0x94, 0x76, 0x35, 0x47, 0xcc, 0x3b, 0xbb, 0xd2, 0xe1, 0x44, 0x2d, 0xf2, 0x06, 0x4c, 0xd2, 0xb0, + 0x23, 0xc9, 0x5f, 0xd7, 0x1c, 0x3c, 0x56, 0xb4, 0x95, 0xc5, 0xd4, 0xba, 0xe6, 0x60, 0xb4, 0x05, + 0x15, 0xaf, 0xf1, 0xcd, 0x84, 0x8d, 0x13, 0x76, 0x53, 0xde, 0x64, 0x2a, 0xee, 0x3a, 0xcc, 0xd8, + 0x9a, 0x83, 0xdb, 0x6d, 0x83, 0x16, 0xe0, 0x07, 0x5d, 0xcd, 0xe9, 0x5b, 0xfc, 0xfd, 0x47, 0x45, + 0xee, 0xd0, 0xae, 0x18, 0x51, 0xfe, 0x9a, 0x82, 0x3c, 0x7f, 0x3f, 0x19, 0xb7, 0x6a, 0xf8, 0x22, + 0x14, 0x7a, 0xa6, 0x6d, 0x38, 0x02, 0x00, 0x4b, 0xab, 0xe7, 0x3d, 0x5f, 0xe1, 0x32, 0x77, 0x38, + 0x83, 0xea, 0xb2, 0xa2, 0xd7, 0x61, 0xc6, 0x33, 0xdd, 0x13, 0xfc, 0x94, 0x23, 0x43, 0x3a, 0x0e, + 0x19, 0xbc, 0x28, 0xbf, 0x83, 0x9f, 0x32, 0x50, 0xb8, 0x02, 0x93, 0x81, 0xe9, 0xac, 0xee, 0x53, + 0xcb, 0x7e, 0x4e, 0xb4, 0x02, 0x33, 0xe4, 0xed, 0xc3, 0x77, 0x88, 0x41, 0x63, 0x9f, 0x1d, 0x5e, + 0x4c, 0x93, 0x21, 0xf7, 0xf4, 0xa2, 0x4e, 0xde, 0xe1, 0x56, 0xdd, 0x7a, 0x0e, 0xeb, 0x4d, 0xfe, + 0x7e, 0x43, 0x67, 0xb0, 0x23, 0x55, 0x6f, 0xc1, 0x0d, 0x3a, 0x46, 0xe7, 0xbc, 0x08, 0x39, 0x7a, + 0x72, 0x60, 0xd7, 0xf2, 0x34, 0xfb, 0x54, 0xbc, 0xcd, 0xd3, 0x5e, 0x9a, 0xca, 0x87, 0x95, 0x4d, + 0xc8, 0x52, 0x02, 0x5a, 0x80, 0x22, 0x3b, 0x6b, 0xe8, 0xf6, 0x3b, 0x54, 0xbf, 0x59, 0xb5, 0x40, + 0x09, 0xdb, 0xfd, 0x0e, 0x52, 0x20, 0xd3, 0x35, 0x75, 0x51, 0x6f, 0x4d, 0x71, 0x3d, 0xe4, 0xb6, + 0x4d, 0x1d, 0x37, 0xea, 0x2a, 0x1d, 0x53, 0x36, 0xa1, 0x12, 0xd2, 0x2b, 0x79, 0xdd, 0xea, 0x69, + 0x96, 0x43, 0x44, 0xee, 0xf1, 0xfe, 0x79, 0x56, 0xa5, 0x6d, 0x95, 0x6d, 0x4a, 0x21, 0xa9, 0xd9, + 0xe8, 0xea, 0xf8, 0x48, 0x1c, 0x2b, 0xd2, 0x1b, 0xe5, 0x8f, 0x12, 0xcc, 0x70, 0x51, 0x27, 0x7b, + 0x65, 0x7a, 0x36, 0x3e, 0xf3, 0x02, 0x54, 0x3a, 0xda, 0x51, 0x93, 0x1e, 0x33, 0xb0, 0x26, 0x28, + 0xef, 0xa1, 0x4e, 0x76, 0xb4, 0x23, 0xaf, 0xe7, 0xa9, 0xfc, 0x5e, 0x82, 0xd9, 0xe0, 0xb6, 0x38, + 0x42, 0xbe, 0x02, 0x20, 0x5e, 0xcf, 0xdd, 0x75, 0x4e, 0xf3, 0x75, 0x16, 0x45, 0x5f, 0xb9, 0xae, + 0x16, 0x39, 0x53, 0x23, 0xbe, 0xef, 0x9a, 0x3a, 0x8d, 0xbe, 0xeb, 0x18, 0x4d, 0xf8, 0x3f, 0xa5, + 0xdc, 0xed, 0x9c, 0xf0, 0x85, 0x60, 0xfc, 0xfd, 0x27, 0x84, 0x69, 0xea, 0xb8, 0x61, 0x9a, 0x1e, + 0x3d, 0x4c, 0x33, 0x49, 0x61, 0x7a, 0x1b, 0x26, 0xfb, 0xbd, 0xb6, 0xa9, 0xe9, 0x4d, 0x0b, 0xdb, + 0xfd, 0xb6, 0xc3, 0xcf, 0x9f, 0x94, 0xa8, 0x0b, 0x11, 0xa5, 0x3e, 0xe8, 0xf1, 0x63, 0x98, 0x7e, + 0xdb, 0x51, 0xcb, 0x7d, 0xdf, 0x9d, 0xf2, 0x3d, 0xaf, 0xe3, 0x1e, 0x61, 0x1d, 0x1c, 0xa6, 0x2f, + 0x42, 0x9e, 0x9e, 0x14, 0xbb, 0xc7, 0x85, 0xe1, 0x48, 0xcd, 0x91, 0xe1, 0x86, 0x8e, 0xae, 0x41, + 0xe6, 0x50, 0xb3, 0x0f, 0xf9, 0xc7, 0x4d, 0xd3, 0xe2, 0x88, 0x8c, 0x3e, 0x6e, 0x53, 0xb3, 0x0f, + 0x55, 0x3a, 0xac, 0xfc, 0x27, 0x05, 0x65, 0x92, 0xf0, 0x84, 0x09, 0xd0, 0x6a, 0x38, 0xa0, 0x4a, + 0xab, 0xe7, 0x7c, 0xfb, 0xf3, 0x72, 0xa3, 0x2f, 0xaa, 0x42, 0x20, 0x90, 0x4a, 0x06, 0x81, 0xb4, + 0x0f, 0x04, 0xa2, 0x07, 0xa0, 0xd9, 0x11, 0x0e, 0x40, 0xdf, 0x86, 0x73, 0xee, 0x29, 0xa0, 0x2f, + 0x1e, 0x49, 0x69, 0x3f, 0x42, 0x70, 0xcc, 0x88, 0xb9, 0x1e, 0xcd, 0x8e, 0xa6, 0xd3, 0xfc, 0xb1, + 0xd3, 0x69, 0x42, 0xfe, 0x2b, 0x24, 0xe6, 0xbf, 0xba, 0x7b, 0xcc, 0x15, 0x7c, 0x07, 0x45, 0xff, + 0x0f, 0xd3, 0x76, 0xbf, 0xd5, 0xc2, 0xb6, 0xbd, 0xdf, 0x6f, 0x37, 0x39, 0xd2, 0x33, 0x6f, 0xa8, + 0x7a, 0x03, 0x3b, 0x0c, 0xe2, 0x7f, 0x97, 0x72, 0xfd, 0x69, 0x4b, 0x7b, 0x82, 0x59, 0x96, 0xf8, + 0x1f, 0xc7, 0xd4, 0x67, 0x91, 0x87, 0x13, 0xf3, 0x6a, 0x36, 0x31, 0xaf, 0xb2, 0xb6, 0x7f, 0x44, + 0x95, 0xbc, 0x3e, 0xfc, 0xb9, 0x77, 0xf8, 0x7b, 0x1a, 0xe5, 0xfa, 0x33, 0xd1, 0xb4, 0xf2, 0xa9, + 0x77, 0x38, 0x1c, 0x57, 0xbd, 0x7f, 0x3e, 0x73, 0xd3, 0xaf, 0xbc, 0x4d, 0x9d, 0xca, 0x6b, 0xc4, + 0xf8, 0x5a, 0xb8, 0x09, 0x79, 0x96, 0x06, 0xc4, 0xe6, 0x13, 0xf2, 0x80, 0xab, 0x6e, 0x92, 0x07, + 0xc4, 0x94, 0x48, 0x0a, 0xf0, 0x73, 0x3d, 0xdb, 0x14, 0xb0, 0x08, 0x0b, 0xb1, 0x8a, 0xe4, 0x2e, + 0xff, 0x89, 0x04, 0x88, 0x8f, 0x9f, 0xa8, 0x5f, 0x34, 0xa6, 0xaf, 0xaf, 0x43, 0x85, 0x75, 0x84, + 0x9a, 0xa3, 0xbb, 0xfc, 0x14, 0x9b, 0xe1, 0x16, 0xa7, 0x6e, 0x5b, 0x28, 0xed, 0x6b, 0x0b, 0x29, + 0x8f, 0xdd, 0xd2, 0x33, 0xd0, 0xcc, 0xb9, 0x1e, 0x6c, 0xe6, 0x44, 0x1f, 0x33, 0x4a, 0x37, 0xc7, + 0xab, 0x90, 0xdd, 0x6e, 0x8e, 0x3f, 0x68, 0xa5, 0xd1, 0x83, 0xf6, 0x97, 0x92, 0xfb, 0xc1, 0x41, + 0xe8, 0x33, 0x93, 0xcf, 0x83, 0xea, 0x95, 0x5f, 0xa4, 0xbd, 0xcf, 0x1c, 0x42, 0x1f, 0xa4, 0x7c, + 0x3e, 0x01, 0x27, 0x39, 0x97, 0x64, 0x92, 0xdf, 0xd1, 0x2e, 0x43, 0x39, 0xe6, 0xeb, 0xb5, 0x92, + 0xed, 0x3b, 0x90, 0x4b, 0x48, 0x83, 0xb9, 0xe3, 0xa6, 0xc1, 0x7c, 0x4c, 0x1a, 0x7c, 0x19, 0x32, + 0x5d, 0x7c, 0x24, 0x4e, 0x36, 0x07, 0x58, 0x91, 0xb2, 0x29, 0xef, 0x43, 0x79, 0x5d, 0x73, 0x5a, + 0x87, 0xc7, 0xf6, 0xb7, 0x2f, 0x41, 0xc1, 0x62, 0x03, 0x22, 0x9a, 0x64, 0xdf, 0x37, 0xa0, 0x3e, + 0xd1, 0x34, 0x9c, 0x5c, 0x5e, 0xe5, 0x6f, 0x00, 0xd5, 0xf0, 0x30, 0xaa, 0xc3, 0x24, 0x3f, 0xc6, + 0x67, 0xad, 0x46, 0x1e, 0x44, 0x8b, 0xe1, 0xaf, 0x4a, 0x03, 0x5f, 0x82, 0x6f, 0x4e, 0xa8, 0xe5, + 0x3d, 0x1f, 0x19, 0xdd, 0x00, 0x7e, 0xf2, 0xdf, 0x3c, 0xc0, 0xde, 0x67, 0xe7, 0x21, 0x11, 0x5e, + 0xb7, 0x7f, 0x73, 0x42, 0x2d, 0xee, 0x09, 0x9a, 0x6f, 0x09, 0x3a, 0xc5, 0x46, 0x8e, 0xa8, 0x91, + 0x25, 0x04, 0x52, 0x90, 0xb7, 0x04, 0x46, 0x46, 0x5f, 0x71, 0xbf, 0x47, 0x68, 0x1b, 0xb6, 0xe3, + 0xf6, 0x7c, 0x62, 0x3e, 0x8e, 0xf5, 0x24, 0xf0, 0x45, 0x13, 0x22, 0xfa, 0x06, 0xcc, 0xf1, 0xf9, + 0x36, 0x76, 0x9a, 0x9a, 0xf7, 0x5d, 0x02, 0x6f, 0xff, 0x5c, 0x0b, 0x8b, 0x8a, 0xfd, 0x94, 0x62, + 0x73, 0x42, 0x9d, 0xdd, 0x8b, 0x19, 0x46, 0x6b, 0x50, 0xe6, 0xdd, 0xf2, 0x3d, 0x52, 0x24, 0xf0, + 0x36, 0xd0, 0x85, 0x70, 0xeb, 0xd8, 0xff, 0xba, 0xbe, 0x39, 0xa1, 0x96, 0x4c, 0x8f, 0x4a, 0xf4, + 0xc4, 0x45, 0xb4, 0x68, 0x31, 0xcb, 0x0b, 0xe9, 0xc5, 0xb0, 0x8c, 0xc0, 0xcb, 0x24, 0xd1, 0x93, + 0xe9, 0x23, 0x13, 0x53, 0x71, 0x29, 0xc4, 0x54, 0x85, 0xb0, 0xa9, 0xc2, 0x07, 0x33, 0xc4, 0x54, + 0xa6, 0xa0, 0x11, 0x25, 0xf3, 0xc9, 0x54, 0xc9, 0xc5, 0xb0, 0x92, 0x23, 0x07, 0x1f, 0x44, 0xc9, + 0xa6, 0x4b, 0x44, 0xf7, 0x61, 0xc6, 0xaf, 0x05, 0x61, 0x70, 0xa0, 0x72, 0x94, 0x58, 0x65, 0x84, + 0xad, 0x3e, 0x6d, 0x86, 0xc7, 0xd0, 0x43, 0x98, 0xe5, 0x52, 0xf7, 0x69, 0x8a, 0x15, 0x62, 0x4b, + 0x54, 0xec, 0x95, 0xb0, 0xd8, 0x98, 0x82, 0x66, 0x73, 0x42, 0x45, 0x66, 0x64, 0x90, 0x68, 0x5c, + 0x00, 0x0c, 0xb3, 0x5a, 0x39, 0xac, 0xf1, 0x98, 0x2e, 0x0b, 0xd1, 0xb8, 0xed, 0x23, 0xa3, 0xdb, + 0x30, 0x25, 0xa4, 0x70, 0xc3, 0xb1, 0x33, 0xfc, 0x8b, 0x11, 0x31, 0x61, 0xcb, 0x89, 0xa7, 0x73, + 0xd3, 0xdd, 0x87, 0x19, 0x21, 0xa8, 0xa3, 0x3d, 0xc1, 0x1c, 0x26, 0xe9, 0x29, 0x7e, 0x5c, 0x79, + 0x14, 0x79, 0x57, 0x21, 0xda, 0xb3, 0xc3, 0x63, 0x44, 0x7b, 0x81, 0x4d, 0x0a, 0xed, 0x55, 0xc2, + 0xda, 0x4b, 0xac, 0xcc, 0x89, 0xf6, 0xec, 0xc8, 0x20, 0x7a, 0x0c, 0xe7, 0x84, 0xe0, 0xa0, 0x5d, + 0xaa, 0x54, 0xf2, 0xd5, 0x88, 0xe4, 0x78, 0xc3, 0x88, 0x3d, 0x07, 0x2c, 0xb3, 0xe6, 0x41, 0x3f, + 0xf5, 0xc4, 0xe9, 0x70, 0x38, 0x45, 0x6b, 0x2a, 0x12, 0x4e, 0xb6, 0x47, 0x45, 0x5b, 0x50, 0x15, + 0x22, 0x74, 0x9e, 0x43, 0x6b, 0x28, 0x7c, 0x80, 0x15, 0x5f, 0x23, 0x6c, 0x4e, 0xa8, 0x15, 0x3b, + 0x38, 0xb2, 0x5e, 0x84, 0x3c, 0x1f, 0x55, 0xde, 0x82, 0x49, 0x8e, 0xb3, 0x3c, 0x25, 0x7f, 0x19, + 0x8a, 0x16, 0xbf, 0x16, 0x90, 0xbd, 0x10, 0x81, 0x6c, 0x36, 0x4e, 0x31, 0xdb, 0xe3, 0x56, 0xfe, + 0x05, 0x30, 0x1d, 0x61, 0x40, 0x1b, 0xf1, 0xa8, 0x7d, 0x31, 0x09, 0xb5, 0xd9, 0xd4, 0x08, 0x6c, + 0xdf, 0x8c, 0x81, 0xed, 0x85, 0x58, 0xd8, 0x76, 0x05, 0xf8, 0x70, 0x7b, 0x23, 0x1e, 0xb7, 0x2f, + 0x26, 0xe1, 0x76, 0x78, 0x11, 0xdc, 0x94, 0x6f, 0xc4, 0x01, 0xf7, 0x85, 0x78, 0xe0, 0x76, 0x45, + 0xf8, 0x91, 0xfb, 0x9b, 0x43, 0x90, 0xfb, 0x85, 0x61, 0xc8, 0xed, 0x4a, 0x8d, 0x87, 0xee, 0xf5, + 0x58, 0xe8, 0x5e, 0x4c, 0x80, 0x6e, 0x57, 0x58, 0x00, 0xbb, 0x37, 0xe2, 0xb1, 0xfb, 0x62, 0x12, + 0x76, 0x7b, 0xba, 0x0a, 0x80, 0xf7, 0xcd, 0x18, 0xf0, 0x5e, 0x88, 0x05, 0x6f, 0xcf, 0x60, 0x1e, + 0x7a, 0xbf, 0x11, 0x87, 0xde, 0x17, 0xe2, 0xd1, 0xdb, 0xd3, 0xb4, 0x0f, 0xbe, 0x1f, 0x0c, 0x82, + 0xef, 0x2b, 0x03, 0xe1, 0xdb, 0x95, 0x17, 0x83, 0xdf, 0x8f, 0x06, 0xe2, 0xf7, 0xd5, 0xc1, 0xf8, + 0xed, 0x0a, 0x8e, 0x03, 0xf0, 0x8d, 0x78, 0x00, 0xbf, 0x98, 0x04, 0xe0, 0x9e, 0xda, 0x03, 0x08, + 0xbe, 0x99, 0x80, 0xe0, 0x4b, 0x89, 0x08, 0xee, 0x0a, 0x0a, 0x41, 0xf8, 0x83, 0x41, 0x10, 0x7e, + 0x65, 0x20, 0x84, 0x7b, 0x1a, 0x8c, 0x62, 0xf8, 0xa3, 0x81, 0x18, 0x7e, 0x75, 0x30, 0x86, 0x7b, + 0x1a, 0x8c, 0x01, 0xf1, 0xaf, 0x0f, 0x06, 0xf1, 0x6b, 0x43, 0x40, 0xdc, 0x95, 0x1d, 0x8b, 0xe2, + 0xeb, 0xb1, 0x28, 0xbe, 0x98, 0x80, 0xe2, 0x5e, 0x64, 0xf9, 0x61, 0x7c, 0x3b, 0x11, 0xc6, 0x2f, + 0x0f, 0x80, 0x71, 0x57, 0x56, 0x04, 0xc7, 0x01, 0x0a, 0x62, 0x78, 0xf5, 0x9f, 0xd3, 0x50, 0xd8, + 0xe2, 0x32, 0xd0, 0x16, 0x94, 0x19, 0x6c, 0xf2, 0x7f, 0x66, 0x07, 0x97, 0xc8, 0xf2, 0x10, 0x2c, + 0x46, 0x75, 0x28, 0xde, 0xc6, 0x0e, 0x97, 0x35, 0xa0, 0x56, 0x96, 0x07, 0x01, 0x32, 0x59, 0x14, + 0xd3, 0x65, 0xd2, 0xa2, 0x02, 0xd9, 0x54, 0x1e, 0x82, 0xcd, 0x68, 0x13, 0x4a, 0x44, 0xa9, 0x6c, + 0xcc, 0x46, 0x83, 0xca, 0x67, 0x79, 0x20, 0x44, 0x23, 0x0c, 0xb3, 0xbb, 0x62, 0x7b, 0x7e, 0x30, + 0x1d, 0xad, 0x8c, 0x96, 0x47, 0xc4, 0x6c, 0xf4, 0x16, 0x94, 0xa8, 0xb7, 0xf2, 0x6f, 0x75, 0x07, + 0xd6, 0xd3, 0xf2, 0x60, 0xc8, 0xa6, 0x06, 0xa6, 0x51, 0xca, 0x85, 0x0d, 0x2e, 0xac, 0xe5, 0x21, + 0xd8, 0xcd, 0x0d, 0xcc, 0x65, 0x0d, 0xa8, 0xb0, 0xe5, 0x41, 0x00, 0x2e, 0x2c, 0xc2, 0x06, 0x02, + 0x16, 0x89, 0xd4, 0xda, 0xf2, 0x40, 0x28, 0x47, 0xef, 0xc2, 0xb4, 0x2f, 0xb0, 0xf9, 0xba, 0x46, + 0xa8, 0xb9, 0xe5, 0x51, 0x80, 0x1d, 0x35, 0x01, 0xf9, 0x43, 0x9b, 0x8b, 0x1f, 0xa5, 0xf6, 0x96, + 0x47, 0x02, 0x78, 0x62, 0x1d, 0xfa, 0x5c, 0x71, 0x9c, 0x3d, 0xb8, 0x08, 0x97, 0x87, 0x40, 0x3c, + 0xda, 0x81, 0x49, 0x66, 0x2f, 0x21, 0x6f, 0x48, 0x35, 0x2e, 0x0f, 0xc3, 0x7a, 0xa2, 0x5f, 0x0f, + 0x91, 0x85, 0xd4, 0x11, 0xaa, 0x72, 0x79, 0x14, 0xd8, 0x27, 0xfa, 0xf5, 0xa9, 0x5d, 0x88, 0x1f, + 0xa5, 0x3a, 0x97, 0x47, 0x82, 0x7f, 0xb4, 0x07, 0x33, 0x7e, 0xbd, 0x8b, 0x27, 0x8c, 0x54, 0xa5, + 0xcb, 0xa3, 0xa5, 0x01, 0x74, 0x07, 0xca, 0xfe, 0x7f, 0x24, 0xd0, 0xc0, 0x7a, 0x5d, 0x1e, 0x9c, + 0x07, 0xd0, 0x3b, 0x50, 0x11, 0xa0, 0x2d, 0x16, 0x3b, 0xb4, 0x70, 0x97, 0x87, 0xe7, 0x04, 0xf4, + 0x1a, 0x64, 0x69, 0xc1, 0x8d, 0xe6, 0xe2, 0xbb, 0x2a, 0xf2, 0x7c, 0x42, 0xe9, 0x8e, 0x1e, 0x42, + 0x95, 0x81, 0x3c, 0x17, 0x7d, 0xaf, 0xad, 0xc7, 0x2c, 0x29, 0xf4, 0x17, 0x69, 0xcc, 0x92, 0x22, + 0x7f, 0x45, 0x7e, 0x0d, 0xaa, 0x01, 0x67, 0x25, 0xb4, 0xcb, 0x83, 0xfd, 0x95, 0x48, 0x56, 0x86, + 0xb8, 0x2c, 0x11, 0xb3, 0x0b, 0x53, 0xbe, 0x1f, 0xaf, 0x08, 0x25, 0xea, 0xe8, 0xc1, 0x5f, 0xc4, + 0xe4, 0x4b, 0x09, 0x0c, 0x9e, 0xd0, 0x26, 0xa0, 0x90, 0x69, 0x08, 0xf5, 0xca, 0x30, 0xeb, 0x10, + 0xe1, 0x57, 0x87, 0x1a, 0x88, 0x2b, 0x24, 0xe0, 0xa6, 0xf1, 0x0a, 0x09, 0xff, 0x01, 0x16, 0xa3, + 0x90, 0xe8, 0x1f, 0x59, 0xef, 0x40, 0xc5, 0xef, 0xa3, 0x21, 0x1b, 0xc6, 0xff, 0x27, 0xe5, 0xb7, + 0x61, 0xd2, 0x6f, 0x43, 0xef, 0xc2, 0x74, 0x30, 0x87, 0x11, 0x62, 0x60, 0x41, 0xf1, 0x7f, 0xe6, + 0x04, 0xe1, 0x21, 0xe1, 0x87, 0x19, 0x92, 0x07, 0x7d, 0x7f, 0xba, 0xf8, 0x03, 0x2b, 0xfa, 0x1f, + 0x8d, 0x3f, 0xb0, 0x62, 0x7e, 0x8f, 0x59, 0xcf, 0x3c, 0x4e, 0xf5, 0xf6, 0xf6, 0x72, 0xf4, 0x5c, + 0xf6, 0xd5, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x70, 0x7c, 0x53, 0x8c, 0xd4, 0x44, 0x00, 0x00, } type DRPCMetainfoClient interface { diff --git a/pkg/pb/metainfo.proto b/pkg/pb/metainfo.proto index 16011cd8f..51f7b02ed 100644 --- a/pkg/pb/metainfo.proto +++ b/pkg/pb/metainfo.proto @@ -215,7 +215,7 @@ message ListSegmentsRequestOld { bytes bucket = 1; bytes prefix = 2; bytes start_after = 3; - bytes end_before = 4; + bytes end_before = 4 [deprecated=true]; bool recursive = 5; int32 limit = 6; fixed32 meta_flags = 7; diff --git a/pkg/storj/metainfo.go b/pkg/storj/metainfo.go index 690468455..693fe52ca 100644 --- a/pkg/storj/metainfo.go +++ b/pkg/storj/metainfo.go @@ -77,9 +77,9 @@ func (create CreateObject) Object(bucket Bucket, path Path) Object { type ListDirection int8 const ( - // Before lists backwards from cursor, without cursor + // Before lists backwards from cursor, without cursor [NOT SUPPORTED] Before = ListDirection(-2) - // Backward lists backwards from cursor, including cursor + // Backward lists backwards from cursor, including cursor [NOT SUPPORTED] Backward = ListDirection(-1) // Forward lists forwards from cursor, including cursor Forward = ListDirection(1) @@ -114,24 +114,12 @@ func (opts ListOptions) NextPage(list ObjectList) ListOptions { return ListOptions{} } - switch opts.Direction { - case Before, Backward: - return ListOptions{ - Prefix: opts.Prefix, - Cursor: list.Items[0].Path, - Direction: Before, - Limit: opts.Limit, - } - case After, Forward: - return ListOptions{ - Prefix: opts.Prefix, - Cursor: list.Items[len(list.Items)-1].Path, - Direction: After, - Limit: opts.Limit, - } + return ListOptions{ + Prefix: opts.Prefix, + Cursor: list.Items[len(list.Items)-1].Path, + Direction: After, + Limit: opts.Limit, } - - return ListOptions{} } // BucketListOptions lists objects @@ -153,22 +141,11 @@ func (opts BucketListOptions) NextPage(list BucketList) BucketListOptions { return BucketListOptions{} } - switch opts.Direction { - case Before, Backward: - return BucketListOptions{ - Cursor: list.Items[0].Name, - Direction: Before, - Limit: opts.Limit, - } - case After, Forward: - return BucketListOptions{ - Cursor: list.Items[len(list.Items)-1].Name, - Direction: After, - Limit: opts.Limit, - } + return BucketListOptions{ + Cursor: list.Items[len(list.Items)-1].Name, + Direction: After, + Limit: opts.Limit, } - - return BucketListOptions{} } // MetainfoLimits lists limits specified for the Metainfo database diff --git a/proto.lock b/proto.lock index 0f3d32db9..eb3436aec 100644 --- a/proto.lock +++ b/proto.lock @@ -2431,7 +2431,13 @@ { "id": 4, "name": "end_before", - "type": "bytes" + "type": "bytes", + "options": [ + { + "name": "deprecated", + "value": "true" + } + ] }, { "id": 5, diff --git a/satellite/metainfo/metainfo.go b/satellite/metainfo/metainfo.go index a5e6bc654..4c35dfecc 100644 --- a/satellite/metainfo/metainfo.go +++ b/satellite/metainfo/metainfo.go @@ -438,7 +438,7 @@ func (endpoint *Endpoint) ListSegmentsOld(ctx context.Context, req *pb.ListSegme return nil, rpcstatus.Error(rpcstatus.InvalidArgument, err.Error()) } - items, more, err := endpoint.metainfo.List(ctx, prefix, string(req.StartAfter), string(req.EndBefore), req.Recursive, req.Limit, req.MetaFlags) + items, more, err := endpoint.metainfo.List(ctx, prefix, string(req.StartAfter), req.Recursive, req.Limit, req.MetaFlags) if err != nil { return nil, rpcstatus.Error(rpcstatus.Internal, err.Error()) } @@ -924,7 +924,7 @@ func (endpoint *Endpoint) setBucketAttribution(ctx context.Context, header *pb.R return rpcstatus.Error(rpcstatus.InvalidArgument, err.Error()) } - items, _, err := endpoint.metainfo.List(ctx, prefix, "", "", true, 1, 0) + items, _, err := endpoint.metainfo.List(ctx, prefix, "", true, 1, 0) if err != nil { endpoint.log.Error("error while listing segments", zap.Error(err)) return rpcstatus.Error(rpcstatus.Internal, err.Error()) @@ -1292,8 +1292,7 @@ func (endpoint *Endpoint) ListObjects(ctx context.Context, req *pb.ObjectListReq metaflags := meta.All // TODO use flags - // TODO find out how EncryptedCursor -> startAfter/endAfter - segments, more, err := endpoint.metainfo.List(ctx, prefix, string(req.EncryptedCursor), "", req.Recursive, req.Limit, metaflags) + segments, more, err := endpoint.metainfo.List(ctx, prefix, string(req.EncryptedCursor), req.Recursive, req.Limit, metaflags) if err != nil { return nil, rpcstatus.Error(rpcstatus.Internal, err.Error()) } diff --git a/satellite/metainfo/service.go b/satellite/metainfo/service.go index fc6503856..037e76578 100644 --- a/satellite/metainfo/service.go +++ b/satellite/metainfo/service.go @@ -196,7 +196,7 @@ func (s *Service) GetWithBytes(ctx context.Context, path string) (pointerBytes [ } // List returns all Path keys in the pointers bucket -func (s *Service) List(ctx context.Context, prefix string, startAfter string, endBefore string, recursive bool, limit int32, +func (s *Service) List(ctx context.Context, prefix string, startAfter string, recursive bool, limit int32, metaFlags uint32) (items []*pb.ListResponse_Item, more bool, err error) { defer mon.Task()(&ctx)(&err) @@ -211,7 +211,6 @@ func (s *Service) List(ctx context.Context, prefix string, startAfter string, en rawItems, more, err := storage.ListV2(ctx, s.db, storage.ListOptions{ Prefix: prefixKey, StartAfter: storage.Key(startAfter), - EndBefore: storage.Key(endBefore), Recursive: recursive, Limit: int(limit), IncludeValue: metaFlags != meta.None, diff --git a/satellite/repair/repair_test.go b/satellite/repair/repair_test.go index 0d245fc48..2b62ab766 100644 --- a/satellite/repair/repair_test.go +++ b/satellite/repair/repair_test.go @@ -597,7 +597,7 @@ func TestRepairMultipleDisqualified(t *testing.T) { // get a remote segment from metainfo metainfo := satellite.Metainfo.Service - listResponse, _, err := metainfo.List(ctx, "", "", "", true, 0, 0) + listResponse, _, err := metainfo.List(ctx, "", "", true, 0, 0) require.NoError(t, err) var path string @@ -1036,7 +1036,7 @@ func getRemoteSegment( // get a remote segment from metainfo metainfo := satellite.Metainfo.Service - listResponse, _, err := metainfo.List(ctx, "", "", "", true, 0, 0) + listResponse, _, err := metainfo.List(ctx, "", "", true, 0, 0) require.NoError(t, err) for _, v := range listResponse { diff --git a/storage/boltdb/client.go b/storage/boltdb/client.go index 2289f5c6a..e2c449166 100644 --- a/storage/boltdb/client.go +++ b/storage/boltdb/client.go @@ -226,12 +226,7 @@ func (client *Client) GetAll(ctx context.Context, keys storage.Keys) (_ storage. func (client *Client) Iterate(ctx context.Context, opts storage.IterateOptions, fn func(context.Context, storage.Iterator) error) (err error) { defer mon.Task()(&ctx)(&err) return client.view(func(bucket *bolt.Bucket) error { - var cursor advancer - if !opts.Reverse { - cursor = forward{bucket.Cursor()} - } else { - cursor = backward{bucket.Cursor()} - } + var cursor advancer = forward{bucket.Cursor()} start := true lastPrefix := []byte{} @@ -307,46 +302,6 @@ func (cursor forward) Advance() (key, value []byte) { return cursor.Next() } -type backward struct { - *bolt.Cursor -} - -func (cursor backward) PositionToFirst(prefix, first storage.Key) (key, value []byte) { - if prefix.IsZero() { - // there's no prefix - if first.IsZero() { - // and no first item, so start from the end - return cursor.Last() - } - } else { - // there's a prefix - if first.IsZero() || storage.AfterPrefix(prefix).Less(first) { - // there's no first, or it's after our prefix - // storage.AfterPrefix("axxx/") is the next item after prefixes - // so we position to the item before - nextkey := storage.AfterPrefix(prefix) - _, _ = cursor.Seek(nextkey) - return cursor.Prev() - } - } - - // otherwise try to position on first or one before that - key, value = cursor.Seek(first) - if !bytes.Equal(key, first) { - key, value = cursor.Prev() - } - return key, value -} - -func (cursor backward) SkipPrefix(prefix storage.Key) (key, value []byte) { - _, _ = cursor.Seek(prefix) - return cursor.Prev() -} - -func (cursor backward) Advance() (key, value []byte) { - return cursor.Prev() -} - // CompareAndSwap atomically compares and swaps oldValue with newValue func (client *Client) CompareAndSwap(ctx context.Context, key storage.Key, oldValue, newValue storage.Value) (err error) { defer mon.Task()(&ctx)(&err) diff --git a/storage/common.go b/storage/common.go index afdb70d8a..74a2b47ab 100644 --- a/storage/common.go +++ b/storage/common.go @@ -85,8 +85,6 @@ type IterateOptions struct { First Key // Recurse, do not collapse items based on Delimiter Recurse bool - // Reverse iterates in reverse order - Reverse bool } // Iterator iterates over a sequence of ListItems diff --git a/storage/iterator.go b/storage/iterator.go index 76ebfa96b..0cbd91009 100644 --- a/storage/iterator.go +++ b/storage/iterator.go @@ -60,26 +60,6 @@ func SortAndCollapse(items Items, prefix []byte) Items { return result } -// ReverseItems reverses items in the list -// items will be reused and modified -// TODO: remove this -func ReverseItems(items Items) Items { - for i := len(items)/2 - 1; i >= 0; i-- { - k := len(items) - 1 - i - items[i], items[k] = items[k], items[i] - } - return items -} - -// ReverseKeys reverses the list of keys -func ReverseKeys(keys Keys) Keys { - for i := len(keys)/2 - 1; i >= 0; i-- { - k := len(keys) - 1 - i - keys[i], keys[k] = keys[k], keys[i] - } - return keys -} - // StaticIterator implements an iterator over list of items type StaticIterator struct { Items Items diff --git a/storage/listv2.go b/storage/listv2.go index 12496ac6a..ac2a499fa 100644 --- a/storage/listv2.go +++ b/storage/listv2.go @@ -5,14 +5,12 @@ package storage import ( "context" - "errors" ) // ListOptions are items that are optional for the LIST method type ListOptions struct { Prefix Key StartAfter Key // StartAfter is relative to Prefix - EndBefore Key // EndBefore is relative to Prefix Recursive bool IncludeValue bool Limit int @@ -24,12 +22,9 @@ type ListOptions struct { // more indicates if the result was truncated. If false // then the result []ListItem includes all requested keys. // If true then the caller must call List again to get more -// results by setting `StartAfter` or `EndBefore` appropriately. +// results by setting `StartAfter` appropriately. func ListV2(ctx context.Context, store KeyValueStore, opts ListOptions) (result Items, more bool, err error) { defer mon.Task()(&ctx)(&err) - if !opts.StartAfter.IsZero() && !opts.EndBefore.IsZero() { - return nil, false, errors.New("start-after and end-before cannot be combined") - } limit := opts.Limit if limit <= 0 || limit > LookupLimit { @@ -37,15 +32,8 @@ func ListV2(ctx context.Context, store KeyValueStore, opts ListOptions) (result } more = true - reverse := !opts.EndBefore.IsZero() - - var first Key - if !reverse { - first = opts.StartAfter - } else { - first = opts.EndBefore - } + first := opts.StartAfter iterate := func(ctx context.Context, it Iterator) error { var item ListItem skipFirst := true @@ -86,23 +74,15 @@ func ListV2(ctx context.Context, store KeyValueStore, opts ListOptions) (result } var firstFull Key - if !reverse && !opts.StartAfter.IsZero() { + if !opts.StartAfter.IsZero() { firstFull = joinKey(opts.Prefix, opts.StartAfter) } - if reverse && !opts.EndBefore.IsZero() { - firstFull = joinKey(opts.Prefix, opts.EndBefore) - } err = store.Iterate(ctx, IterateOptions{ Prefix: opts.Prefix, First: firstFull, - Reverse: reverse, Recurse: opts.Recursive, }, iterate) - if reverse { - result = ReverseItems(result) - } - return result, more, err } diff --git a/storage/postgreskv/alternateclient.go b/storage/postgreskv/alternateclient.go index 1395b13b0..03d79dc30 100644 --- a/storage/postgreskv/alternateclient.go +++ b/storage/postgreskv/alternateclient.go @@ -57,29 +57,6 @@ FROM ( ) x ORDER BY p LIMIT $4 -` - - alternateReverseQuery = ` -SELECT DISTINCT - $2::BYTEA || x.localpath AS p, - first_value(x.metadata) OVER (PARTITION BY x.localpath ORDER BY x.fullpath) AS m -FROM ( - SELECT - pd.fullpath, - local_path(pd.fullpath, $2::BYTEA, set_byte(' '::BYTEA, 0, b.delim)) AS localpath, - pd.metadata - FROM - pathdata pd, - buckets b - WHERE - b.bucketname = $1::BYTEA - AND pd.bucket = b.bucketname - AND pd.fullpath >= $2::BYTEA - AND ($2::BYTEA = ''::BYTEA OR pd.fullpath < bytea_increment($2::BYTEA)) - AND ($3::BYTEA = ''::BYTEA OR pd.fullpath <= $3::BYTEA) -) x -ORDER BY p DESC -LIMIT $4 ` ) @@ -120,13 +97,7 @@ func (opi *alternateOrderedPostgresIterator) doNextQuery(ctx context.Context) (_ if start == nil { start = opi.opts.First } - var query string - if opi.opts.Reverse { - query = alternateReverseQuery - } else { - query = alternateForwardQuery - } - return opi.client.pgConn.Query(query, []byte(opi.bucket), []byte(opi.opts.Prefix), []byte(start), opi.batchSize+1) + return opi.client.pgConn.Query(alternateForwardQuery, []byte(opi.bucket), []byte(opi.opts.Prefix), []byte(start), opi.batchSize+1) } func newAlternateOrderedPostgresIterator(ctx context.Context, altClient *AlternateClient, opts storage.IterateOptions, batchSize int) (_ *alternateOrderedPostgresIterator, err error) { diff --git a/storage/postgreskv/client.go b/storage/postgreskv/client.go index 0f062c096..fd7909be7 100644 --- a/storage/postgreskv/client.go +++ b/storage/postgreskv/client.go @@ -6,7 +6,6 @@ package postgreskv import ( "context" "database/sql" - "fmt" "github.com/lib/pq" "github.com/zeebo/errs" @@ -254,28 +253,18 @@ func (opi *orderedPostgresIterator) doNextQuery(ctx context.Context) (_ *sql.Row } var query string if !opi.opts.Recurse { - if opi.opts.Reverse { - query = "SELECT p, m FROM list_directory_reverse($1::BYTEA, $2::BYTEA, $3::BYTEA, $4) ld(p, m)" - } else { - query = "SELECT p, m FROM list_directory($1::BYTEA, $2::BYTEA, $3::BYTEA, $4) ld(p, m)" - } + query = "SELECT p, m FROM list_directory($1::BYTEA, $2::BYTEA, $3::BYTEA, $4) ld(p, m)" } else { - startCmp := ">=" - orderDir := "" - if opi.opts.Reverse { - startCmp = "<=" - orderDir = " DESC" - } - query = fmt.Sprintf(` + query = ` SELECT fullpath, metadata FROM pathdata WHERE bucket = $1::BYTEA AND ($2::BYTEA = ''::BYTEA OR fullpath >= $2::BYTEA) AND ($2::BYTEA = ''::BYTEA OR fullpath < bytea_increment($2::BYTEA)) - AND ($3::BYTEA = ''::BYTEA OR fullpath %s $3::BYTEA) - ORDER BY fullpath%s + AND ($3::BYTEA = ''::BYTEA OR fullpath >= $3::BYTEA) + ORDER BY fullpath LIMIT $4 - `, startCmp, orderDir) + ` } return opi.client.pgConn.Query(query, []byte(opi.bucket), []byte(opi.opts.Prefix), []byte(start), opi.batchSize+1) } diff --git a/storage/redis/client.go b/storage/redis/client.go index 40f392219..aa4e5d58e 100644 --- a/storage/redis/client.go +++ b/storage/redis/client.go @@ -164,21 +164,13 @@ func (client *Client) GetAll(ctx context.Context, keys storage.Keys) (_ storage. // Iterate iterates over items based on opts func (client *Client) Iterate(ctx context.Context, opts storage.IterateOptions, fn func(context.Context, storage.Iterator) error) (err error) { defer mon.Task()(&ctx)(&err) - var all storage.Items - if !opts.Reverse { - all, err = client.allPrefixedItems(opts.Prefix, opts.First, nil) - } else { - all, err = client.allPrefixedItems(opts.Prefix, nil, opts.First) - } + all, err := client.allPrefixedItems(opts.Prefix, opts.First, nil) if err != nil { return err } if !opts.Recurse { all = storage.SortAndCollapse(all, opts.Prefix) } - if opts.Reverse { - all = storage.ReverseItems(all) - } return fn(ctx, &storage.StaticIterator{ Items: all, }) diff --git a/storage/storelogger/logger.go b/storage/storelogger/logger.go index 3172dcec6..08a6c1e6b 100644 --- a/storage/storelogger/logger.go +++ b/storage/storelogger/logger.go @@ -74,7 +74,6 @@ func (store *Logger) Iterate(ctx context.Context, opts storage.IterateOptions, f zap.ByteString("prefix", opts.Prefix), zap.ByteString("first", opts.First), zap.Bool("recurse", opts.Recurse), - zap.Bool("reverse", opts.Reverse), ) return store.store.Iterate(ctx, opts, func(ctx context.Context, it storage.Iterator) error { return fn(ctx, storage.IteratorFunc(func(ctx context.Context, item *storage.ListItem) bool { diff --git a/storage/teststore/store.go b/storage/teststore/store.go index 70becb4c7..01f205298 100644 --- a/storage/teststore/store.go +++ b/storage/teststore/store.go @@ -30,7 +30,6 @@ type Client struct { Put int List int GetAll int - ReverseList int Delete int Close int Iterate int @@ -202,12 +201,7 @@ func (store *Client) Iterate(ctx context.Context, opts storage.IterateOptions, f return errInternal } - var cursor advancer - if !opts.Reverse { - cursor = &forward{newCursor(store)} - } else { - cursor = &backward{newCursor(store)} - } + var cursor advancer = &forward{newCursor(store)} cursor.PositionToFirst(opts.Prefix, opts.First) var lastPrefix storage.Key diff --git a/storage/testsuite/long_bench.go b/storage/testsuite/long_bench.go index 4a2d90713..09da28255 100644 --- a/storage/testsuite/long_bench.go +++ b/storage/testsuite/long_bench.go @@ -194,19 +194,12 @@ func BenchmarkPathOperationsInLargeDb(b *testing.B, store storage.KeyValueStore) } doTest("DeepRecursive", deepRecursive) - doTest("DeepRecursiveReverse", deepRecursiveReverse) doTest("DeepNonRecursive", deepNonRecursive) - doTest("DeepNonRecursiveReverse", deepNonRecursiveReverse) doTest("ShallowRecursive", shallowRecursive) - doTest("ShallowRecursiveReverse", shallowRecursiveReverse) doTest("ShallowNonRecursive", shallowNonRecursive) - doTest("ShallowNonRecursiveReverse", shallowNonRecursiveReverse) doTest("TopRecursiveLimit", topRecursiveLimit) - doTest("TopRecursiveLimitReverse", topRecursiveLimitReverse) doTest("TopRecursiveStartAt", topRecursiveStartAt) - doTest("TopRecursiveStartAtReverse", topRecursiveStartAtReverse) doTest("TopNonRecursive", topNonRecursive) - doTest("TopNonRecursiveReverse", topNonRecursiveReverse) cleanupStore(b, store) } @@ -347,10 +340,7 @@ func benchAndVerifyIteration(b *testing.B, store storage.KeyValueStore, opts *ve if result.Key.Equal(lastKey) { errorf("got the same key (%q) twice in a row, not on a lookup boundary!", lastKey) } - if opts.iterateOpts.Reverse && !lastKey.IsZero() && lastKey.Less(result.Key) { - errorf("KeyValueStore returned items out of order! %q > %q", result.Key, lastKey) - } - if !opts.iterateOpts.Reverse && result.Key.Less(lastKey) { + if result.Key.Less(lastKey) { errorf("KeyValueStore returned items out of order! %q < %q", result.Key, lastKey) } if result.IsPrefix { @@ -410,31 +400,6 @@ func deepRecursive(b *testing.B, store storage.KeyValueStore) { benchAndVerifyIteration(b, store, opts) } -func deepRecursiveReverse(b *testing.B, store storage.KeyValueStore) { - opts := &verifyOpts{ - iterateOpts: storage.IterateOptions{ - Prefix: storage.Key(largestLevel2Directory), - Recurse: true, - Reverse: true, - }, - } - - // these are not expected to exhaust all available items - opts.doIterations = 500 - opts.batchSize = storage.LookupLimit - opts.expectCount = opts.doIterations * opts.batchSize - - // verify with: - // select encode(fullpath, 'escape') from ( - // select rank() over (order by fullpath desc), fullpath from pathdata - // where fullpath < bytea_increment($1::bytea) - // ) x where rank = ($2 * $3); - // where $1 = largestLevel2Directory, $2 = doIterations, and $3 = batchSize - opts.expectLastKey = storage.Key("Peronosporales/hateless/apetaly/poikilocythemia/capped/abrash/dugout/notodontid/jasponyx/cassican/brunelliaceous") - - benchAndVerifyIteration(b, store, opts) -} - func deepNonRecursive(b *testing.B, store storage.KeyValueStore) { opts := &verifyOpts{ iterateOpts: storage.IterateOptions{ @@ -460,32 +425,6 @@ func deepNonRecursive(b *testing.B, store storage.KeyValueStore) { benchAndVerifyIteration(b, store, opts) } -func deepNonRecursiveReverse(b *testing.B, store storage.KeyValueStore) { - opts := &verifyOpts{ - iterateOpts: storage.IterateOptions{ - Prefix: storage.Key(largestLevel2Directory), - Recurse: false, - Reverse: true, - }, - doIterations: 1, - batchSize: 10000, - } - - // verify with: - // select count(*) from list_directory(''::bytea, $1::bytea) ld(fp, md); - // where $1 is largestLevel2Directory - opts.expectCount = 119 - - // verify with: - // select encode(fp, 'escape') from ( - // select * from list_directory(''::bytea, $1::bytea) ld(fp, md) - // ) x order by fp limit 1; - // where $1 is largestLevel2Directory - opts.expectLastKey = storage.Key("Peronosporales/hateless/Absyrtus") - - benchAndVerifyIteration(b, store, opts) -} - func shallowRecursive(b *testing.B, store storage.KeyValueStore) { opts := &verifyOpts{ iterateOpts: storage.IterateOptions{ @@ -515,36 +454,6 @@ func shallowRecursive(b *testing.B, store storage.KeyValueStore) { benchAndVerifyIteration(b, store, opts) } -func shallowRecursiveReverse(b *testing.B, store storage.KeyValueStore) { - opts := &verifyOpts{ - iterateOpts: storage.IterateOptions{ - Prefix: storage.Key(largestSingleDirectory), - Recurse: true, - Reverse: true, - }, - } - - // verify with: - // select count(*) from pathdata - // where fullpath > $1::bytea and fullpath < bytea_increment($1::bytea); - // where $1 = largestSingleDirectory - opts.expectCount = 18574 - - // verify with: - // select convert_from(fullpath, 'UTF8') from pathdata - // where fullpath > $1::bytea and fullpath < bytea_increment($1::bytea) - // order by fullpath limit 1; - // where $1 = largestSingleDirectory - opts.expectLastKey = storage.Key("Peronosporales/hateless/tod/unricht/sniveling/Puyallup/Aaronite") - - // i didn't plan it this way, but expectedCount happens to have some nicely-sized factors for - // our purposes with no messy remainder. 74 * 251 = 18574 - opts.doIterations = 74 - opts.batchSize = 251 - - benchAndVerifyIteration(b, store, opts) -} - func shallowNonRecursive(b *testing.B, store storage.KeyValueStore) { opts := &verifyOpts{ iterateOpts: storage.IterateOptions{ @@ -570,32 +479,6 @@ func shallowNonRecursive(b *testing.B, store storage.KeyValueStore) { benchAndVerifyIteration(b, store, opts) } -func shallowNonRecursiveReverse(b *testing.B, store storage.KeyValueStore) { - opts := &verifyOpts{ - iterateOpts: storage.IterateOptions{ - Prefix: storage.Key(largestSingleDirectory), - Recurse: false, - Reverse: true, - }, - doIterations: 2, - batchSize: 10000, - } - - // verify with: - // select count(*) from list_directory(''::bytea, $1::bytea) ld(fp, md); - // where $1 is largestSingleDirectory - opts.expectCount = 18574 - - // verify with: - // select encode(fp, 'escape') from ( - // select * from list_directory(''::bytea, $1::bytea) ld(fp, md) - // ) x order by fp limit 1; - // where $1 = largestSingleDirectory - opts.expectLastKey = storage.Key("Peronosporales/hateless/tod/unricht/sniveling/Puyallup/Aaronite") - - benchAndVerifyIteration(b, store, opts) -} - func topRecursiveLimit(b *testing.B, store storage.KeyValueStore) { opts := &verifyOpts{ iterateOpts: storage.IterateOptions{ @@ -618,29 +501,6 @@ func topRecursiveLimit(b *testing.B, store storage.KeyValueStore) { benchAndVerifyIteration(b, store, opts) } -func topRecursiveLimitReverse(b *testing.B, store storage.KeyValueStore) { - opts := &verifyOpts{ - iterateOpts: storage.IterateOptions{ - Recurse: true, - Reverse: true, - }, - doIterations: 100, - batchSize: 10000, - } - - // not expected to exhaust items - opts.expectCount = opts.doIterations * opts.batchSize - - // verify with: - // select encode(fullpath, 'escape') from ( - // select rank() over (order by fullpath desc), fullpath from pathdata - // ) x where rank = $1; - // where $1 = expectCount - opts.expectLastKey = storage.Key("nonresuscitation/synchronically/cabook/homeozoic/inclinatorium/iguanodont/thiophenol/congeliturbation/Alaric") - - benchAndVerifyIteration(b, store, opts) -} - func topRecursiveStartAt(b *testing.B, store storage.KeyValueStore) { opts := &verifyOpts{ iterateOpts: storage.IterateOptions{ @@ -666,36 +526,6 @@ func topRecursiveStartAt(b *testing.B, store storage.KeyValueStore) { benchAndVerifyIteration(b, store, opts) } -func topRecursiveStartAtReverse(b *testing.B, store storage.KeyValueStore) { - opts := &verifyOpts{ - iterateOpts: storage.IterateOptions{ - Recurse: true, - Reverse: true, - }, - doIterations: 61, - batchSize: 10000, - } - - // this is pretty arbitrary. just the key 100 positions before the end of the Peronosporales/hateless/ dir. - opts.iterateOpts.First = storage.Key("Peronosporales/hateless/warrener/anthropomancy/geisotherm/wickerwork") - - // we *do* expect to exhaust the available items this time. - // verify with: - // select count(*) from ( - // select fullpath from pathdata where fullpath <= $1::bytea order by fullpath desc limit $2 - // ) x; - // where $1 = iterateOpts.First and $2 = (doIterations * batchSize) - opts.expectCount = 608405 - - // since expectCount < (doIterations * batchSize), and we're going in reverse, the last key read - // should be the first one lexicographically. - // verify with: - // select encode(fullpath, 'escape') from pathdata order by fullpath limit 1; - opts.expectLastKey = storage.Key("Lissamphibia") - - benchAndVerifyIteration(b, store, opts) -} - func topNonRecursive(b *testing.B, store storage.KeyValueStore) { opts := &verifyOpts{ iterateOpts: storage.IterateOptions{ @@ -718,27 +548,6 @@ func topNonRecursive(b *testing.B, store storage.KeyValueStore) { benchAndVerifyIteration(b, store, opts) } -func topNonRecursiveReverse(b *testing.B, store storage.KeyValueStore) { - opts := &verifyOpts{ - iterateOpts: storage.IterateOptions{ - Recurse: false, - Reverse: true, - }, - doIterations: 1, - batchSize: 10000, - } - - // verify with: - // select count(*) from list_directory(''::bytea, ''::bytea); - opts.expectCount = 21 - - // verify with: - // select encode(fullpath, 'escape') from pathdata order by fullpath limit 1; - opts.expectLastKey = storage.Key("Lissamphibia") - - benchAndVerifyIteration(b, store, opts) -} - func cleanupBigPathset(tb testing.TB, store storage.KeyValueStore) { if *noCleanDb { tb.Skip("Instructed not to clean up this KeyValueStore after long benchmarks are complete.") diff --git a/storage/testsuite/test_iterate.go b/storage/testsuite/test_iterate.go index 492d3a012..fd2929840 100644 --- a/storage/testsuite/test_iterate.go +++ b/storage/testsuite/test_iterate.go @@ -42,17 +42,6 @@ func testIterate(t *testing.T, store storage.KeyValueStore) { newItem("g", "g", false), newItem("h", "h", false), }}, - {"no limits reverse", - storage.IterateOptions{ - Reverse: true, - }, storage.Items{ - newItem("h", "h", false), - newItem("g", "g", false), - newItem("c/", "", true), - newItem("c", "c", false), - newItem("b/", "", true), - newItem("a", "a", false), - }}, {"at a", storage.IterateOptions{ @@ -66,14 +55,6 @@ func testIterate(t *testing.T, store storage.KeyValueStore) { newItem("h", "h", false), }}, - {"reverse at a", - storage.IterateOptions{ - First: storage.Key("a"), - Reverse: true, - }, storage.Items{ - newItem("a", "a", false), - }}, - {"after a", storage.IterateOptions{ First: storage.NextKey(storage.Key("a")), @@ -126,16 +107,6 @@ func testIterate(t *testing.T, store storage.KeyValueStore) { newItem("g", "g", false), newItem("h", "h", false), }}, - {"reverse after e", - storage.IterateOptions{ - First: storage.NextKey(storage.Key("e")), - Reverse: true, - }, storage.Items{ - newItem("c/", "", true), - newItem("c", "c", false), - newItem("b/", "", true), - newItem("a", "a", false), - }}, {"prefix b slash", storage.IterateOptions{ Prefix: storage.Key("b/"), diff --git a/storage/testsuite/test_iterate_all.go b/storage/testsuite/test_iterate_all.go index b862f6ac9..976708f7c 100644 --- a/storage/testsuite/test_iterate_all.go +++ b/storage/testsuite/test_iterate_all.go @@ -61,21 +61,6 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) { newItem("g", "g", false), newItem("h", "h", false), }}, - {"no limits reverse", - storage.IterateOptions{ - Recurse: true, Reverse: true, - }, storage.Items{ - newItem("h", "h", false), - newItem("g", "g", false), - newItem("c/1", "c/1", false), - newItem("c//", "c//", false), - newItem("c/", "c/", false), - newItem("c", "c", false), - newItem("b/3", "b/3", false), - newItem("b/2", "b/2", false), - newItem("b/1", "b/1", false), - newItem("a", "a", false), - }}, {"at a", storage.IterateOptions{ @@ -93,13 +78,6 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) { newItem("g", "g", false), newItem("h", "h", false), }}, - {"at a reverse", - storage.IterateOptions{ - First: storage.Key("a"), - Recurse: true, Reverse: true, - }, storage.Items{ - newItem("a", "a", false), - }}, {"after a", storage.IterateOptions{ @@ -180,20 +158,6 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) { newItem("g", "g", false), newItem("h", "h", false), }}, - {"at e reverse", - storage.IterateOptions{ - First: storage.Key("e"), - Recurse: true, Reverse: true, - }, storage.Items{ - newItem("c/1", "c/1", false), - newItem("c//", "c//", false), - newItem("c/", "c/", false), - newItem("c", "c", false), - newItem("b/3", "b/3", false), - newItem("b/2", "b/2", false), - newItem("b/1", "b/1", false), - newItem("a", "a", false), - }}, {"prefix b slash", storage.IterateOptions{ @@ -221,23 +185,6 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) { newItem("b/2", "b/2", false), newItem("b/3", "b/3", false), }}, - {"reverse prefix b slash", - storage.IterateOptions{ - Prefix: storage.Key("b/"), - Recurse: true, Reverse: true, - }, storage.Items{ - newItem("b/3", "b/3", false), - newItem("b/2", "b/2", false), - newItem("b/1", "b/1", false), - }}, - {"reverse prefix b slash at b slash 2", - storage.IterateOptions{ - Prefix: storage.Key("b/"), First: storage.Key("b/2"), - Recurse: true, Reverse: true, - }, storage.Items{ - newItem("b/2", "b/2", false), - newItem("b/1", "b/1", false), - }}, {"prefix c slash", storage.IterateOptions{ @@ -248,15 +195,6 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) { newItem("c//", "c//", false), newItem("c/1", "c/1", false), }}, - {"reverse prefix c slash", - storage.IterateOptions{ - Prefix: storage.Key("c/"), - Recurse: true, Reverse: true, - }, storage.Items{ - newItem("c/1", "c/1", false), - newItem("c//", "c//", false), - newItem("c/", "c/", false), - }}, {"prefix c slash slash", storage.IterateOptions{ @@ -265,12 +203,5 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) { }, storage.Items{ newItem("c//", "c//", false), }}, - {"reverse prefix c slash slash", - storage.IterateOptions{ - Prefix: storage.Key("c//"), - Recurse: true, Reverse: true, - }, storage.Items{ - newItem("c//", "c//", false), - }}, }) } diff --git a/storage/testsuite/test_listv2.go b/storage/testsuite/test_listv2.go index f26741ff3..0d2e89273 100644 --- a/storage/testsuite/test_listv2.go +++ b/storage/testsuite/test_listv2.go @@ -122,49 +122,6 @@ func testListV2(t *testing.T, store storage.KeyValueStore) { newItem("my-album/", "", true), }, }, - {"end before 2 recursive", - storage.ListOptions{ - Recursive: true, - EndBefore: storage.Key("music/z-song5.mp3"), - Limit: 2, - }, - true, storage.Items{ - newItem("music/my-album/song3.mp3", "", false), - newItem("music/my-album/song4.mp3", "", false), - }, - }, - {"end before non-existing 2 recursive", - storage.ListOptions{ - Recursive: true, - EndBefore: storage.Key("music/my-album/song5.mp3"), - Limit: 2, - }, - true, storage.Items{ - newItem("music/my-album/song3.mp3", "", false), - newItem("music/my-album/song4.mp3", "", false), - }, - }, - {"end before 2", - storage.ListOptions{ - Prefix: storage.Key("music/"), - EndBefore: storage.Key("z-song5.mp3"), - Limit: 2, - }, - true, storage.Items{ - newItem("a-song2.mp3", "", false), - newItem("my-album/", "", true), - }, - }, - {"end before 2 prefixed", - storage.ListOptions{ - Prefix: storage.Key("music/my-album/"), - EndBefore: storage.Key("song4.mp3"), - Limit: 2, - }, - false, storage.Items{ - newItem("song3.mp3", "", false), - }, - }, } for _, test := range tests { diff --git a/storage/testsuite/test_prefix.go b/storage/testsuite/test_prefix.go index 971a0efbf..1584d42bc 100644 --- a/storage/testsuite/test_prefix.go +++ b/storage/testsuite/test_prefix.go @@ -39,30 +39,12 @@ func testPrefix(t *testing.T, store storage.KeyValueStore) { newItem("x-b/2", "b/2", false), newItem("x-b/3", "b/3", false), }}, - {"reverse prefix x dash b slash", - storage.IterateOptions{ - Prefix: storage.Key("x-"), First: storage.Key("x-b/3"), - Recurse: true, Reverse: true, - }, storage.Items{ - newItem("x-b/3", "b/3", false), - newItem("x-b/2", "b/2", false), - newItem("x-b/1", "b/1", false), - newItem("x-a", "a", false), - }}, {"prefix x dash b slash", storage.IterateOptions{ Prefix: storage.Key("x-"), First: storage.Key("x-b"), }, storage.Items{ newItem("x-b/", "", true), }}, - {"reverse x dash b slash", - storage.IterateOptions{ - Prefix: storage.Key("x-"), First: storage.Key("x-b/2"), - Reverse: true, - }, storage.Items{ - newItem("x-b/", "", true), - newItem("x-a", "a", false), - }}, {"prefix y- slash", storage.IterateOptions{ Prefix: storage.Key("y-"), diff --git a/uplink/metainfo/client_old.go b/uplink/metainfo/client_old.go index bd071f6ad..831d547e6 100644 --- a/uplink/metainfo/client_old.go +++ b/uplink/metainfo/client_old.go @@ -134,7 +134,7 @@ func (client *Client) DeleteSegmentOld(ctx context.Context, bucket string, path } // ListSegmentsOld lists the available segments -func (client *Client) ListSegmentsOld(ctx context.Context, bucket string, prefix, startAfter, endBefore storj.Path, recursive bool, limit int32, metaFlags uint32) (items []ListItem, more bool, err error) { +func (client *Client) ListSegmentsOld(ctx context.Context, bucket string, prefix, startAfter, ignoredEndBefore storj.Path, recursive bool, limit int32, metaFlags uint32) (items []ListItem, more bool, err error) { defer mon.Task()(&ctx)(&err) response, err := client.client.ListSegmentsOld(ctx, &pb.ListSegmentsRequestOld{ @@ -142,7 +142,6 @@ func (client *Client) ListSegmentsOld(ctx context.Context, bucket string, prefix Bucket: []byte(bucket), Prefix: []byte(prefix), StartAfter: []byte(startAfter), - EndBefore: []byte(endBefore), Recursive: recursive, Limit: limit, MetaFlags: metaFlags, diff --git a/uplink/metainfo/kvmetainfo/objects.go b/uplink/metainfo/kvmetainfo/objects.go index ed578707d..6fc14c019 100644 --- a/uplink/metainfo/kvmetainfo/objects.go +++ b/uplink/metainfo/kvmetainfo/objects.go @@ -169,15 +169,9 @@ func (db *DB) ListObjects(ctx context.Context, bucket string, options storj.List prefix: bucket, } - var startAfter, endBefore string + var startAfter string switch options.Direction { // TODO for now we are supporting only storj.After - // case storj.Before: - // // before lists backwards from cursor, without cursor - // endBefore = options.Cursor - // case storj.Backward: - // // backward lists backwards from cursor, including cursor - // endBefore = keyAfter(options.Cursor) // case storj.Forward: // // forward lists forwards from cursor, including cursor // startAfter = keyBefore(options.Cursor) @@ -188,12 +182,7 @@ func (db *DB) ListObjects(ctx context.Context, bucket string, options storj.List return storj.ObjectList{}, errClass.New("invalid direction %d", options.Direction) } - // TODO: remove this hack-fix of specifying the last key - if options.Cursor == "" && (options.Direction == storj.Before || options.Direction == storj.Backward) { - endBefore = "\x7f\x7f\x7f\x7f\x7f\x7f\x7f" - } - - items, more, err := objects.List(ctx, options.Prefix, startAfter, endBefore, options.Recursive, options.Limit, meta.All) + items, more, err := objects.List(ctx, options.Prefix, startAfter, options.Recursive, options.Limit, meta.All) if err != nil { return storj.ObjectList{}, err } diff --git a/uplink/metainfo/kvmetainfo/objects_test.go b/uplink/metainfo/kvmetainfo/objects_test.go index acbf70f7d..a0f3a1030 100644 --- a/uplink/metainfo/kvmetainfo/objects_test.go +++ b/uplink/metainfo/kvmetainfo/objects_test.go @@ -294,8 +294,6 @@ func TestListObjectsEmpty(t *testing.T) { // TODO for now we are supporting only storj.After for _, direction := range []storj.ListDirection{ - // storj.Before, - // storj.Backward, // storj.Forward, storj.After, } { @@ -334,311 +332,80 @@ func TestListObjects(t *testing.T) { result []string }{ { - options: options("", "", storj.After, 0), + options: options("", "", 0), result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"}, }, { - options: options("", "`", storj.After, 0), + options: options("", "`", 0), result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"}, }, { - options: options("", "b", storj.After, 0), + options: options("", "b", 0), result: []string{"b/", "bb", "c"}, }, { - options: options("", "c", storj.After, 0), + options: options("", "c", 0), result: []string{}, }, { - options: options("", "ca", storj.After, 0), + options: options("", "ca", 0), result: []string{}, }, { - options: options("", "", storj.After, 1), + options: options("", "", 1), more: true, result: []string{"a"}, }, { - options: options("", "`", storj.After, 1), + options: options("", "`", 1), more: true, result: []string{"a"}, }, { - options: options("", "aa", storj.After, 1), + options: options("", "aa", 1), more: true, result: []string{"b"}, }, { - options: options("", "c", storj.After, 1), + options: options("", "c", 1), result: []string{}, }, { - options: options("", "ca", storj.After, 1), + options: options("", "ca", 1), result: []string{}, }, { - options: options("", "", storj.After, 2), + options: options("", "", 2), more: true, result: []string{"a", "a/"}, }, { - options: options("", "`", storj.After, 2), + options: options("", "`", 2), more: true, result: []string{"a", "a/"}, }, { - options: options("", "aa", storj.After, 2), + options: options("", "aa", 2), more: true, result: []string{"b", "b/"}, }, { - options: options("", "bb", storj.After, 2), + options: options("", "bb", 2), result: []string{"c"}, }, { - options: options("", "c", storj.After, 2), + options: options("", "c", 2), result: []string{}, }, { - options: options("", "ca", storj.After, 2), + options: options("", "ca", 2), result: []string{}, }, { - options: optionsRecursive("", "", storj.After, 0), + options: optionsRecursive("", "", 0), result: []string{"a", "a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc", "aa", "b", "b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc", "bb", "c"}, }, { - options: options("a", "", storj.After, 0), + options: options("a", "", 0), result: []string{"xa", "xaa", "xb", "xbb", "xc"}, }, { - options: options("a/", "", storj.After, 0), + options: options("a/", "", 0), result: []string{"xa", "xaa", "xb", "xbb", "xc"}, }, { - options: options("a/", "xb", storj.After, 0), + options: options("a/", "xb", 0), result: []string{"xbb", "xc"}, }, { - options: optionsRecursive("", "a/xbb", storj.After, 5), + options: optionsRecursive("", "a/xbb", 5), more: true, result: []string{"a/xc", "aa", "b", "b/ya", "b/yaa"}, }, { - options: options("a/", "xaa", storj.After, 2), + options: options("a/", "xaa", 2), more: true, result: []string{"xb", "xbb"}, }, - // TODO commented until we will decide if we will support direction for object listing - // - // { - // options: options("", "", storj.Forward, 0), - // result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"}, - // }, { - // options: options("", "`", storj.Forward, 0), - // result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"}, - // }, { - // options: options("", "b", storj.Forward, 0), - // result: []string{"b", "b/", "bb", "c"}, - // }, { - // options: options("", "c", storj.Forward, 0), - // result: []string{"c"}, - // }, { - // options: options("", "ca", storj.Forward, 0), - // result: []string{}, - // }, { - // options: options("", "", storj.Forward, 1), - // more: true, - // result: []string{"a"}, - // }, { - // options: options("", "`", storj.Forward, 1), - // more: true, - // result: []string{"a"}, - // }, { - // options: options("", "aa", storj.Forward, 1), - // more: true, - // result: []string{"aa"}, - // }, { - // options: options("", "c", storj.Forward, 1), - // result: []string{"c"}, - // }, { - // options: options("", "ca", storj.Forward, 1), - // result: []string{}, - // }, { - // options: options("", "", storj.Forward, 2), - // more: true, - // result: []string{"a", "a/"}, - // }, { - // options: options("", "`", storj.Forward, 2), - // more: true, - // result: []string{"a", "a/"}, - // }, { - // options: options("", "aa", storj.Forward, 2), - // more: true, - // result: []string{"aa", "b"}, - // }, { - // options: options("", "bb", storj.Forward, 2), - // result: []string{"bb", "c"}, - // }, { - // options: options("", "c", storj.Forward, 2), - // result: []string{"c"}, - // }, { - // options: options("", "ca", storj.Forward, 2), - // result: []string{}, - // }, { - // options: optionsRecursive("", "", storj.Forward, 0), - // result: []string{"a", "a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc", "aa", "b", "b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc", "bb", "c"}, - // }, { - // options: options("a", "", storj.Forward, 0), - // result: []string{"xa", "xaa", "xb", "xbb", "xc"}, - // }, { - // options: options("a/", "", storj.Forward, 0), - // result: []string{"xa", "xaa", "xb", "xbb", "xc"}, - // }, { - // options: options("a/", "xb", storj.Forward, 0), - // result: []string{"xb", "xbb", "xc"}, - // }, { - // options: optionsRecursive("", "a/xbb", storj.Forward, 5), - // more: true, - // result: []string{"a/xbb", "a/xc", "aa", "b", "b/ya"}, - // }, { - // options: options("a/", "xaa", storj.Forward, 2), - // more: true, - // result: []string{"xaa", "xb"}, - // }, { - // options: options("", "", storj.Backward, 0), - // result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"}, - // }, { - // options: options("", "`", storj.Backward, 0), - // result: []string{}, - // }, { - // options: options("", "b", storj.Backward, 0), - // result: []string{"a", "a/", "aa", "b"}, - // }, { - // options: options("", "c", storj.Backward, 0), - // result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"}, - // }, { - // options: options("", "ca", storj.Backward, 0), - // result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"}, - // }, { - // options: options("", "", storj.Backward, 1), - // more: true, - // result: []string{"c"}, - // }, { - // options: options("", "`", storj.Backward, 1), - // result: []string{}, - // }, { - // options: options("", "aa", storj.Backward, 1), - // more: true, - // result: []string{"aa"}, - // }, { - // options: options("", "c", storj.Backward, 1), - // more: true, - // result: []string{"c"}, - // }, { - // options: options("", "ca", storj.Backward, 1), - // more: true, - // result: []string{"c"}, - // }, { - // options: options("", "", storj.Backward, 2), - // more: true, - // result: []string{"bb", "c"}, - // }, { - // options: options("", "`", storj.Backward, 2), - // result: []string{}, - // }, { - // options: options("", "a/", storj.Backward, 2), - // result: []string{"a"}, - // }, { - // options: options("", "bb", storj.Backward, 2), - // more: true, - // result: []string{"b/", "bb"}, - // }, { - // options: options("", "c", storj.Backward, 2), - // more: true, - // result: []string{"bb", "c"}, - // }, { - // options: options("", "ca", storj.Backward, 2), - // more: true, - // result: []string{"bb", "c"}, - // }, { - // options: optionsRecursive("", "", storj.Backward, 0), - // result: []string{"a", "a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc", "aa", "b", "b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc", "bb", "c"}, - // }, { - // options: options("a", "", storj.Backward, 0), - // result: []string{"xa", "xaa", "xb", "xbb", "xc"}, - // }, { - // options: options("a/", "", storj.Backward, 0), - // result: []string{"xa", "xaa", "xb", "xbb", "xc"}, - // }, { - // options: options("a/", "xb", storj.Backward, 0), - // result: []string{"xa", "xaa", "xb"}, - // }, { - // options: optionsRecursive("", "b/yaa", storj.Backward, 5), - // more: true, - // result: []string{"a/xc", "aa", "b", "b/ya", "b/yaa"}, - // }, { - // options: options("a/", "xbb", storj.Backward, 2), - // more: true, - // result: []string{"xb", "xbb"}, - // }, { - // options: options("", "", storj.Before, 0), - // result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"}, - // }, { - // options: options("", "`", storj.Before, 0), - // result: []string{}, - // }, { - // options: options("", "a", storj.Before, 0), - // result: []string{}, - // }, { - // options: options("", "b", storj.Before, 0), - // result: []string{"a", "a/", "aa"}, - // }, { - // options: options("", "c", storj.Before, 0), - // result: []string{"a", "a/", "aa", "b", "b/", "bb"}, - // }, { - // options: options("", "ca", storj.Before, 0), - // result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"}, - // }, { - // options: options("", "", storj.Before, 1), - // more: true, - // result: []string{"c"}, - // }, { - // options: options("", "`", storj.Before, 1), - // result: []string{}, - // }, { - // options: options("", "a/", storj.Before, 1), - // result: []string{"a"}, - // }, { - // options: options("", "c", storj.Before, 1), - // more: true, - // result: []string{"bb"}, - // }, { - // options: options("", "ca", storj.Before, 1), - // more: true, - // result: []string{"c"}, - // }, { - // options: options("", "", storj.Before, 2), - // more: true, - // result: []string{"bb", "c"}, - // }, { - // options: options("", "`", storj.Before, 2), - // result: []string{}, - // }, { - // options: options("", "a/", storj.Before, 2), - // result: []string{"a"}, - // }, { - // options: options("", "bb", storj.Before, 2), - // more: true, - // result: []string{"b", "b/"}, - // }, { - // options: options("", "c", storj.Before, 2), - // more: true, - // result: []string{"b/", "bb"}, - // }, { - // options: options("", "ca", storj.Before, 2), - // more: true, - // result: []string{"bb", "c"}, - // }, { - // options: optionsRecursive("", "", storj.Before, 0), - // result: []string{"a", "a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc", "aa", "b", "b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc", "bb", "c"}, - // }, { - // options: options("a", "", storj.Before, 0), - // result: []string{"xa", "xaa", "xb", "xbb", "xc"}, - // }, { - // options: options("a/", "", storj.Before, 0), - // result: []string{"xa", "xaa", "xb", "xbb", "xc"}, - // }, { - // options: options("a/", "xb", storj.Before, 0), - // result: []string{"xa", "xaa"}, - // }, { - // options: optionsRecursive("", "b/yaa", storj.Before, 5), - // more: true, - // result: []string{"a/xbb", "a/xc", "aa", "b", "b/ya"}, - // }, { - // options: options("a/", "xbb", storj.Before, 2), - // more: true, - // result: []string{"xaa", "xb"}, - // }, } { errTag := fmt.Sprintf("%d. %+v", i, tt) @@ -655,20 +422,20 @@ func TestListObjects(t *testing.T) { } }) } -func options(prefix, cursor string, direction storj.ListDirection, limit int) storj.ListOptions { +func options(prefix, cursor string, limit int) storj.ListOptions { return storj.ListOptions{ Prefix: prefix, Cursor: cursor, - Direction: direction, + Direction: storj.After, Limit: limit, } } -func optionsRecursive(prefix, cursor string, direction storj.ListDirection, limit int) storj.ListOptions { +func optionsRecursive(prefix, cursor string, limit int) storj.ListOptions { return storj.ListOptions{ Prefix: prefix, Cursor: cursor, - Direction: direction, + Direction: storj.After, Limit: limit, Recursive: true, } diff --git a/uplink/metainfo/kvmetainfo/prefixed.go b/uplink/metainfo/kvmetainfo/prefixed.go index f4861a3a6..caacc69cb 100644 --- a/uplink/metainfo/kvmetainfo/prefixed.go +++ b/uplink/metainfo/kvmetainfo/prefixed.go @@ -59,8 +59,8 @@ func (o *prefixedObjStore) Delete(ctx context.Context, path storj.Path) (err err return o.store.Delete(ctx, storj.JoinPaths(o.prefix, path)) } -func (o *prefixedObjStore) List(ctx context.Context, prefix, startAfter, endBefore storj.Path, recursive bool, limit int, metaFlags uint32) (items []objects.ListItem, more bool, err error) { +func (o *prefixedObjStore) List(ctx context.Context, prefix, startAfter storj.Path, recursive bool, limit int, metaFlags uint32) (items []objects.ListItem, more bool, err error) { defer mon.Task()(&ctx)(&err) - return o.store.List(ctx, storj.JoinPaths(o.prefix, prefix), startAfter, endBefore, recursive, limit, metaFlags) + return o.store.List(ctx, storj.JoinPaths(o.prefix, prefix), startAfter, recursive, limit, metaFlags) } diff --git a/uplink/storage/objects/store.go b/uplink/storage/objects/store.go index 83c697759..79a928cc8 100644 --- a/uplink/storage/objects/store.go +++ b/uplink/storage/objects/store.go @@ -43,7 +43,7 @@ type Store interface { Get(ctx context.Context, path storj.Path) (rr ranger.Ranger, meta Meta, err error) Put(ctx context.Context, path storj.Path, data io.Reader, metadata pb.SerializableMeta, expiration time.Time) (meta Meta, err error) Delete(ctx context.Context, path storj.Path) (err error) - List(ctx context.Context, prefix, startAfter, endBefore storj.Path, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) + List(ctx context.Context, prefix, startAfter storj.Path, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) } type objStore struct { @@ -123,11 +123,11 @@ func (o *objStore) Delete(ctx context.Context, path storj.Path) (err error) { return err } -func (o *objStore) List(ctx context.Context, prefix, startAfter, endBefore storj.Path, recursive bool, limit int, metaFlags uint32) ( +func (o *objStore) List(ctx context.Context, prefix, startAfter storj.Path, recursive bool, limit int, metaFlags uint32) ( items []ListItem, more bool, err error) { defer mon.Task()(&ctx)(&err) - strItems, more, err := o.store.List(ctx, prefix, startAfter, endBefore, o.pathCipher, recursive, limit, metaFlags) + strItems, more, err := o.store.List(ctx, prefix, startAfter, o.pathCipher, recursive, limit, metaFlags) if err != nil { return nil, false, err } diff --git a/uplink/storage/streams/shim.go b/uplink/storage/streams/shim.go index 668794e49..c2b784005 100644 --- a/uplink/storage/streams/shim.go +++ b/uplink/storage/streams/shim.go @@ -21,7 +21,7 @@ type Store interface { Get(ctx context.Context, path storj.Path, pathCipher storj.CipherSuite) (ranger.Ranger, Meta, error) Put(ctx context.Context, path storj.Path, pathCipher storj.CipherSuite, data io.Reader, metadata []byte, expiration time.Time) (Meta, error) Delete(ctx context.Context, path storj.Path, pathCipher storj.CipherSuite) error - List(ctx context.Context, prefix, startAfter, endBefore storj.Path, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) + List(ctx context.Context, prefix, startAfter storj.Path, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) } type shimStore struct { @@ -66,8 +66,8 @@ func (s *shimStore) Delete(ctx context.Context, path storj.Path, pathCipher stor } // List parses the passed in path and dispatches to the typed store. -func (s *shimStore) List(ctx context.Context, prefix storj.Path, startAfter storj.Path, endBefore storj.Path, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) { +func (s *shimStore) List(ctx context.Context, prefix storj.Path, startAfter storj.Path, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) { defer mon.Task()(&ctx)(&err) - return s.store.List(ctx, ParsePath(prefix), startAfter, endBefore, pathCipher, recursive, limit, metaFlags) + return s.store.List(ctx, ParsePath(prefix), startAfter, pathCipher, recursive, limit, metaFlags) } diff --git a/uplink/storage/streams/store.go b/uplink/storage/streams/store.go index f67793a91..938d8a1c5 100644 --- a/uplink/storage/streams/store.go +++ b/uplink/storage/streams/store.go @@ -59,7 +59,7 @@ type typedStore interface { Get(ctx context.Context, path Path, pathCipher storj.CipherSuite) (ranger.Ranger, Meta, error) Put(ctx context.Context, path Path, pathCipher storj.CipherSuite, data io.Reader, metadata []byte, expiration time.Time) (Meta, error) Delete(ctx context.Context, path Path, pathCipher storj.CipherSuite) error - List(ctx context.Context, prefix Path, startAfter, endBefore string, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) + List(ctx context.Context, prefix Path, startAfter string, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) } // streamStore is a store for streams. It implements typedStore as part of an ongoing migration @@ -582,7 +582,7 @@ func pathForKey(raw string) paths.Unencrypted { } // List all the paths inside l/, stripping off the l/ prefix -func (s *streamStore) List(ctx context.Context, prefix Path, startAfter, endBefore string, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) { +func (s *streamStore) List(ctx context.Context, prefix Path, startAfter string, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) { defer mon.Task()(&ctx)(&err) // TODO use flags with listing @@ -611,9 +611,9 @@ func (s *streamStore) List(ctx context.Context, prefix Path, startAfter, endBefo encPrefix = paths.NewEncrypted(encPrefix.Raw()[:lastSlashIdx]) } - // We have to encrypt startAfter and endBefore but only if they don't contain a bucket. - // They contain a bucket if and only if the prefix has no bucket. This is why they are raw - // strings instead of a typed string: it's either a bucket or an unencrypted path component + // We have to encrypt startAfter but only if it doesn't contain a bucket. + // It contains a bucket if and only if the prefix has no bucket. This is why it is a raw + // string instead of a typed string: it's either a bucket or an unencrypted path component // and that isn't known at compile time. needsEncryption := prefix.Bucket() != "" if needsEncryption { diff --git a/uplink/storage/streams/store_test.go b/uplink/storage/streams/store_test.go index 517fda20b..c8fc559a5 100644 --- a/uplink/storage/streams/store_test.go +++ b/uplink/storage/streams/store_test.go @@ -132,7 +132,7 @@ func TestStreamsInterruptedDelete(t *testing.T) { require.NoError(t, err) // Ensure the item shows when we list - listItems, _, err := streamStore.List(ctx, bucketName, "", "", storj.EncNull, true, 10, meta.None) + listItems, _, err := streamStore.List(ctx, bucketName, "", storj.EncNull, true, 10, meta.None) require.NoError(t, err) require.True(t, len(listItems) == 1) @@ -158,7 +158,7 @@ func TestStreamsInterruptedDelete(t *testing.T) { // It should *still* show when we list, as we've only deleted one // segment - listItems, _, err = streamStore.List(ctx, bucketName, "", "", storj.EncNull, true, 10, meta.None) + listItems, _, err = streamStore.List(ctx, bucketName, "", storj.EncNull, true, 10, meta.None) require.NoError(t, err) require.True(t, len(listItems) == 1) @@ -168,7 +168,7 @@ func TestStreamsInterruptedDelete(t *testing.T) { _ = streamStore.Delete(ctx, fullPath, storj.EncNull) // Now it should have 0 list items - listItems, _, err = streamStore.List(ctx, bucketName, "", "", storj.EncNull, true, 10, meta.None) + listItems, _, err = streamStore.List(ctx, bucketName, "", storj.EncNull, true, 10, meta.None) require.NoError(t, err) require.True(t, len(listItems) == 0) }) @@ -203,39 +203,39 @@ func TestStreamStoreList(t *testing.T) { prefix := bucketName // should list all - items, more, err := streamStore.List(ctx, prefix, "", "", storj.EncNull, true, 10, meta.None) + items, more, err := streamStore.List(ctx, prefix, "", storj.EncNull, true, 10, meta.None) require.NoError(t, err) require.False(t, more) require.Equal(t, len(objects), len(items)) // should list first two and more = true - items, more, err = streamStore.List(ctx, prefix, "", "", storj.EncNull, true, 2, meta.None) + items, more, err = streamStore.List(ctx, prefix, "", storj.EncNull, true, 2, meta.None) require.NoError(t, err) require.True(t, more) require.Equal(t, 2, len(items)) // should list only prefixes - items, more, err = streamStore.List(ctx, prefix, "", "", storj.EncNull, false, 10, meta.None) + items, more, err = streamStore.List(ctx, prefix, "", storj.EncNull, false, 10, meta.None) require.NoError(t, err) require.False(t, more) require.Equal(t, 2, len(items)) // should list only BBBB bucket prefix = storj.JoinPaths(bucketName, "bbbb") - items, more, err = streamStore.List(ctx, prefix, "", "", storj.EncNull, false, 10, meta.None) + items, more, err = streamStore.List(ctx, prefix, "", storj.EncNull, false, 10, meta.None) require.NoError(t, err) require.False(t, more) require.Equal(t, 3, len(items)) // should list only BBBB bucket after afile - items, more, err = streamStore.List(ctx, prefix, "afile1", "", storj.EncNull, false, 10, meta.None) + items, more, err = streamStore.List(ctx, prefix, "afile1", storj.EncNull, false, 10, meta.None) require.NoError(t, err) require.False(t, more) require.Equal(t, 2, len(items)) // should list nothing prefix = storj.JoinPaths(bucketName, "cccc") - items, more, err = streamStore.List(ctx, prefix, "", "", storj.EncNull, true, 10, meta.None) + items, more, err = streamStore.List(ctx, prefix, "", storj.EncNull, true, 10, meta.None) require.NoError(t, err) require.False(t, more) require.Equal(t, 0, len(items))