From 66507ae5daf424d4e340cb84c6e7b73c3a647386 Mon Sep 17 00:00:00 2001 From: Tobias Schottdorf Date: Sat, 30 Sep 2017 09:39:50 -0400 Subject: [PATCH] storage: add "noop" intent resolution poisoning option Manual testing in https://github.com/cockroachdb/cockroach/issues/15997 surfaced that one limiting factor in resolving many intents is contention on the transaction's abort cache entry. In one extreme test, I wrote 10E6 abortable intents into a single range, in which case the GC queue sends very large batches of intent resolution requests for the same transaction to the intent resolver. These requests all overlapped on the transaction's abort cache key, causing very slow progress, and ultimately preventing the GC queue from making a dent in the minute allotted to it. Generally this appears to be a somewhat atypical case, but since @nvanbenschoten observed something similar in https://github.com/cockroachdb/cockroach/issues/18199 it seemed well worth addressing, by means of 1. allow intent resolutions to not touch the abort span 2. correctly declare the keys for `ResolveIntent{,Range}` to only declare the abort cache key if it is actually going to be accessed. With these changes, the gc queue was able to clear out a million intents comfortably on my older 13" MacBook (single node). Also use this option in the intent resolver, where possible -- most transactions don't receive abort cache entries, and intents are often "found" by multiple conflicting writers. We want to avoid adding artificial contention there, though in many situations the same intent is resolved and so a conflict still exists. Migration: a new field number was added to the proto and the old one preserved. We continue to populate it. Downstream of Raft, we use the new field but if it's unset, synthesize from the deprecated field. I believe this is sufficient and we can just remove all traces of the old field in v1.3. (v1.1 uses the old, v1.2 uses the new with compatibility for the old, v1.3 only the new field). --- pkg/roachpb/api.pb.go | 711 ++++++++++++++++------------ pkg/roachpb/api.proto | 22 +- pkg/storage/gc_queue.go | 15 +- pkg/storage/intent_resolver.go | 45 +- pkg/storage/replica_command.go | 67 ++- pkg/storage/replica_command_test.go | 90 ++++ pkg/storage/replica_test.go | 6 +- pkg/storage/span_set.go | 16 + 8 files changed, 633 insertions(+), 339 deletions(-) create mode 100644 pkg/storage/replica_command_test.go diff --git a/pkg/roachpb/api.pb.go b/pkg/roachpb/api.pb.go index 678bc0bfe4c6..45247523f09d 100644 --- a/pkg/roachpb/api.pb.go +++ b/pkg/roachpb/api.pb.go @@ -286,6 +286,50 @@ func (x *PushTxnType) UnmarshalJSON(data []byte) error { } func (PushTxnType) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{1} } +type PoisonType int32 + +const ( + // Sender is at an older version and uses the deprecated_poison field. + PoisonType_Deprecated PoisonType = 0 + // Make no changes to the abort cache of the associated transaction. + PoisonType_Noop PoisonType = 1 + // Poison the abort cache of the associated transaction. + PoisonType_Do PoisonType = 2 + // Clear any entry in the abort cache of the associated transaction. + PoisonType_Clear PoisonType = 3 +) + +var PoisonType_name = map[int32]string{ + 0: "Deprecated", + 1: "Noop", + 2: "Do", + 3: "Clear", +} +var PoisonType_value = map[string]int32{ + "Deprecated": 0, + "Noop": 1, + "Do": 2, + "Clear": 3, +} + +func (x PoisonType) Enum() *PoisonType { + p := new(PoisonType) + *p = x + return p +} +func (x PoisonType) String() string { + return proto.EnumName(PoisonType_name, int32(x)) +} +func (x *PoisonType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(PoisonType_value, data, "PoisonType") + if err != nil { + return err + } + *x = PoisonType(value) + return nil +} +func (PoisonType) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{2} } + type ExportStorageProvider int32 const ( @@ -330,7 +374,7 @@ func (x *ExportStorageProvider) UnmarshalJSON(data []byte) error { *x = ExportStorageProvider(value) return nil } -func (ExportStorageProvider) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{2} } +func (ExportStorageProvider) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{3} } // RangeInfo describes a range which executed a request. It contains // the range descriptor and lease information at the time of execution. @@ -1060,7 +1104,10 @@ type ResolveIntentRequest struct { Status TransactionStatus `protobuf:"varint,3,opt,name=status,enum=cockroach.roachpb.TransactionStatus" json:"status"` // Optionally poison the sequence cache for the transaction the intent's // range. - Poison bool `protobuf:"varint,4,opt,name=poison" json:"poison"` + // + // TODO(tschottdorf): this can be removed in CockroachDB v1.3. + DeprecatedPoison bool `protobuf:"varint,4,opt,name=deprecated_poison,json=deprecatedPoison" json:"deprecated_poison"` + Poison PoisonType `protobuf:"varint,5,opt,name=poison,enum=cockroach.roachpb.PoisonType" json:"poison"` } func (m *ResolveIntentRequest) Reset() { *m = ResolveIntentRequest{} } @@ -1091,7 +1138,10 @@ type ResolveIntentRangeRequest struct { Status TransactionStatus `protobuf:"varint,3,opt,name=status,enum=cockroach.roachpb.TransactionStatus" json:"status"` // Optionally poison the sequence cache for the transaction on all ranges // on which the intents reside. - Poison bool `protobuf:"varint,4,opt,name=poison" json:"poison"` + // + // TODO(tschottdorf): this can be removed in CockroachDB v1.3. + DeprecatedPoison bool `protobuf:"varint,4,opt,name=deprecated_poison,json=deprecatedPoison" json:"deprecated_poison"` + Poison PoisonType `protobuf:"varint,5,opt,name=poison,enum=cockroach.roachpb.PoisonType" json:"poison"` } func (m *ResolveIntentRangeRequest) Reset() { *m = ResolveIntentRangeRequest{} } @@ -1882,6 +1932,7 @@ func init() { proto.RegisterType((*BatchResponse_Header)(nil), "cockroach.roachpb.BatchResponse.Header") proto.RegisterEnum("cockroach.roachpb.ReadConsistencyType", ReadConsistencyType_name, ReadConsistencyType_value) proto.RegisterEnum("cockroach.roachpb.PushTxnType", PushTxnType_name, PushTxnType_value) + proto.RegisterEnum("cockroach.roachpb.PoisonType", PoisonType_name, PoisonType_value) proto.RegisterEnum("cockroach.roachpb.ExportStorageProvider", ExportStorageProvider_name, ExportStorageProvider_value) } func (this *GetRequest) Equal(that interface{}) bool { @@ -2712,6 +2763,9 @@ func (this *ResolveIntentRequest) Equal(that interface{}) bool { if this.Status != that1.Status { return false } + if this.DeprecatedPoison != that1.DeprecatedPoison { + return false + } if this.Poison != that1.Poison { return false } @@ -2751,6 +2805,9 @@ func (this *ResolveIntentRangeRequest) Equal(that interface{}) bool { if this.Status != that1.Status { return false } + if this.DeprecatedPoison != that1.DeprecatedPoison { + return false + } if this.Poison != that1.Poison { return false } @@ -5248,12 +5305,15 @@ func (m *ResolveIntentRequest) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintApi(dAtA, i, uint64(m.Status)) dAtA[i] = 0x20 i++ - if m.Poison { + if m.DeprecatedPoison { dAtA[i] = 1 } else { dAtA[i] = 0 } i++ + dAtA[i] = 0x28 + i++ + i = encodeVarintApi(dAtA, i, uint64(m.Poison)) return i, nil } @@ -5319,12 +5379,15 @@ func (m *ResolveIntentRangeRequest) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintApi(dAtA, i, uint64(m.Status)) dAtA[i] = 0x20 i++ - if m.Poison { + if m.DeprecatedPoison { dAtA[i] = 1 } else { dAtA[i] = 0 } i++ + dAtA[i] = 0x28 + i++ + i = encodeVarintApi(dAtA, i, uint64(m.Poison)) return i, nil } @@ -8119,6 +8182,7 @@ func (m *ResolveIntentRequest) Size() (n int) { n += 1 + l + sovApi(uint64(l)) n += 1 + sovApi(uint64(m.Status)) n += 2 + n += 1 + sovApi(uint64(m.Poison)) return n } @@ -8139,6 +8203,7 @@ func (m *ResolveIntentRangeRequest) Size() (n int) { n += 1 + l + sovApi(uint64(l)) n += 1 + sovApi(uint64(m.Status)) n += 2 + n += 1 + sovApi(uint64(m.Poison)) return n } @@ -14417,7 +14482,7 @@ func (m *ResolveIntentRequest) Unmarshal(dAtA []byte) error { } case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Poison", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeprecatedPoison", wireType) } var v int for shift := uint(0); ; shift += 7 { @@ -14434,7 +14499,26 @@ func (m *ResolveIntentRequest) Unmarshal(dAtA []byte) error { break } } - m.Poison = bool(v != 0) + m.DeprecatedPoison = bool(v != 0) + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Poison", wireType) + } + m.Poison = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Poison |= (PoisonType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -14646,7 +14730,7 @@ func (m *ResolveIntentRangeRequest) Unmarshal(dAtA []byte) error { } case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Poison", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeprecatedPoison", wireType) } var v int for shift := uint(0); ; shift += 7 { @@ -14663,7 +14747,26 @@ func (m *ResolveIntentRangeRequest) Unmarshal(dAtA []byte) error { break } } - m.Poison = bool(v != 0) + m.DeprecatedPoison = bool(v != 0) + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Poison", wireType) + } + m.Poison = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Poison |= (PoisonType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -22056,297 +22159,301 @@ var ( func init() { proto.RegisterFile("cockroach/pkg/roachpb/api.proto", fileDescriptorApi) } var fileDescriptorApi = []byte{ - // 4671 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5c, 0xdd, 0x6f, 0x1b, 0xc7, - 0x76, 0xf7, 0xf2, 0x43, 0x22, 0x0f, 0x49, 0x89, 0x1a, 0xcb, 0x36, 0xad, 0x38, 0xa2, 0x4c, 0x7f, - 0x26, 0x4e, 0x28, 0xc7, 0xae, 0x7b, 0xe3, 0x34, 0xc1, 0xb5, 0x45, 0xc9, 0x32, 0xfd, 0xa9, 0x2c, - 0xa9, 0x38, 0x37, 0x69, 0xef, 0x76, 0xb5, 0x3b, 0x22, 0xb7, 0x22, 0x77, 0xe9, 0xdd, 0xa5, 0x25, - 0xa5, 0x68, 0x0b, 0x14, 0x28, 0x5a, 0x04, 0xe8, 0x17, 0xd0, 0x87, 0x16, 0x7d, 0xb8, 0x01, 0x6e, - 0x1f, 0x2e, 0x50, 0xa0, 0xff, 0x40, 0x51, 0x14, 0x7d, 0x4b, 0xd1, 0x3e, 0xdc, 0x97, 0xb6, 0x17, - 0x7d, 0x30, 0x7a, 0xdd, 0x97, 0x8b, 0x3e, 0x15, 0x28, 0xf2, 0x92, 0xa7, 0x62, 0xbe, 0x96, 0xbb, - 0xe4, 0x2e, 0x49, 0x29, 0x1b, 0xa4, 0x7d, 0x22, 0x79, 0x66, 0xce, 0x6f, 0x67, 0xce, 0xcc, 0x9c, - 0xf9, 0xcd, 0x9c, 0xb3, 0x84, 0xb2, 0x66, 0x69, 0x7b, 0xb6, 0xa5, 0x6a, 0xed, 0xd5, 0xde, 0x5e, - 0x6b, 0x95, 0x7e, 0xeb, 0xed, 0xac, 0xaa, 0x3d, 0xa3, 0xda, 0xb3, 0x2d, 0xd7, 0x42, 0x0b, 0x5e, - 0x85, 0x2a, 0x2f, 0x5c, 0x5a, 0x09, 0xd7, 0xd1, 0x55, 0x57, 0x65, 0x4a, 0x4b, 0x95, 0xf0, 0x1a, - 0xd8, 0xb6, 0x2d, 0xdb, 0xe1, 0x75, 0x2e, 0x86, 0xd7, 0xe9, 0x62, 0x57, 0xf5, 0x21, 0x5d, 0x0f, - 0xd6, 0x72, 0x5c, 0xcb, 0x56, 0x5b, 0x78, 0x15, 0x9b, 0x2d, 0xc3, 0x14, 0x1f, 0x44, 0xeb, 0x85, - 0xa6, 0x71, 0x8d, 0xcb, 0x41, 0x8d, 0xbe, 0x6b, 0x74, 0x56, 0xdb, 0x1d, 0x6d, 0xd5, 0x35, 0xba, - 0xd8, 0x71, 0xd5, 0x6e, 0x8f, 0xd7, 0xab, 0x86, 0xd4, 0x73, 0x6d, 0x55, 0x33, 0xcc, 0xd6, 0xaa, - 0x8d, 0x35, 0xcb, 0xd6, 0xb1, 0xae, 0x38, 0x3d, 0xd5, 0xe4, 0xf5, 0x17, 0x5b, 0x56, 0xcb, 0xa2, - 0x5f, 0x57, 0xc9, 0x37, 0x26, 0xad, 0xfc, 0x0e, 0x64, 0x65, 0xd5, 0x6c, 0xe1, 0xba, 0xb9, 0x6b, - 0xa1, 0xf7, 0x21, 0xa5, 0x63, 0x47, 0x2b, 0x49, 0x2b, 0xd2, 0xd5, 0xdc, 0x8d, 0x4a, 0x75, 0xc4, - 0x74, 0x55, 0x5a, 0x77, 0x1d, 0x3b, 0x9a, 0x6d, 0xf4, 0x5c, 0xcb, 0x5e, 0x4b, 0x7d, 0xf9, 0xb2, - 0x7c, 0x42, 0xa6, 0x5a, 0xe8, 0x97, 0x20, 0xdd, 0xc1, 0xaa, 0x83, 0x4b, 0x09, 0xaa, 0x5e, 0x0a, - 0x51, 0x7f, 0x44, 0xca, 0xb9, 0x12, 0xab, 0x5c, 0x79, 0x25, 0xc1, 0x9c, 0x8c, 0x9d, 0x9e, 0x65, - 0x3a, 0xf8, 0x3e, 0x56, 0x75, 0x6c, 0xa3, 0xeb, 0x90, 0x74, 0x0f, 0xcc, 0x52, 0x92, 0xc2, 0x2c, - 0x87, 0xc0, 0x34, 0x6d, 0xd5, 0x74, 0x54, 0xcd, 0x35, 0x2c, 0x53, 0x26, 0x55, 0xd1, 0xbb, 0x90, - 0xb3, 0xb1, 0xd3, 0xef, 0x62, 0xda, 0xe1, 0x52, 0x8a, 0x6a, 0x9e, 0x09, 0xd1, 0x6c, 0xf4, 0x54, - 0x53, 0x06, 0x56, 0x97, 0x7c, 0x47, 0x65, 0xc8, 0x98, 0xfd, 0xae, 0xb2, 0x87, 0x0f, 0x9d, 0x52, - 0x7a, 0x45, 0xba, 0x9a, 0xe4, 0xad, 0x9b, 0x35, 0xfb, 0xdd, 0x87, 0xf8, 0xd0, 0x41, 0x35, 0xc8, - 0xd9, 0xa4, 0xd3, 0x8a, 0x61, 0xee, 0x5a, 0x4e, 0x69, 0x66, 0x25, 0x79, 0x35, 0x77, 0xe3, 0x5c, - 0x94, 0x69, 0x88, 0x19, 0x39, 0x02, 0xd8, 0x42, 0xe0, 0x54, 0x1e, 0x03, 0x6c, 0x62, 0x57, 0xc6, - 0xcf, 0xfb, 0xd8, 0x71, 0xd1, 0x6d, 0x98, 0x69, 0xd3, 0x9e, 0x72, 0x43, 0x47, 0x35, 0x74, 0x2d, - 0x43, 0x80, 0x7e, 0xfa, 0xb2, 0x2c, 0xc9, 0x5c, 0xe1, 0xbd, 0xd4, 0x2f, 0xbe, 0x28, 0x4b, 0x95, - 0xdf, 0x95, 0x20, 0x47, 0xf1, 0x98, 0xd9, 0x50, 0x6d, 0x08, 0xf0, 0x7c, 0x58, 0xf3, 0x02, 0x36, - 0x1e, 0x85, 0x46, 0x55, 0x48, 0xbf, 0x50, 0x3b, 0xfd, 0x71, 0xc3, 0xf7, 0x11, 0x29, 0x97, 0x59, - 0xb5, 0xca, 0xdf, 0x49, 0x00, 0x5b, 0xfd, 0x18, 0x3a, 0x45, 0x26, 0xce, 0x54, 0x4f, 0x16, 0x13, - 0x87, 0x56, 0x46, 0xe7, 0x60, 0xc6, 0x30, 0x3b, 0x86, 0x89, 0xe9, 0x44, 0xc9, 0xf0, 0x42, 0x2e, - 0x43, 0x4b, 0x90, 0xde, 0xe9, 0x18, 0xa6, 0x4e, 0xe7, 0x82, 0x28, 0x64, 0x22, 0x6e, 0x44, 0x19, - 0x72, 0xb4, 0xf9, 0x31, 0xda, 0xb0, 0xf2, 0x73, 0x09, 0x4e, 0xd5, 0x2c, 0x53, 0x37, 0xc8, 0xd4, - 0x54, 0x3b, 0xdf, 0xa5, 0x79, 0x6e, 0x41, 0x16, 0x1f, 0xf4, 0x14, 0xa6, 0x99, 0x9c, 0x30, 0xa4, - 0x19, 0x7c, 0xd0, 0xa3, 0xdf, 0xa6, 0xb0, 0xdb, 0xaf, 0xc1, 0xe9, 0xe1, 0x2e, 0xc6, 0x69, 0xc2, - 0x7f, 0x91, 0x60, 0xae, 0x6e, 0x1a, 0xee, 0x77, 0x69, 0x3b, 0xcf, 0x08, 0xc9, 0x11, 0x23, 0xa0, - 0xeb, 0x50, 0xdc, 0x55, 0x8d, 0xce, 0x53, 0xb3, 0x69, 0x75, 0x77, 0x1c, 0xd7, 0x32, 0xb1, 0x13, - 0xb0, 0xd5, 0x48, 0x29, 0x37, 0xdb, 0x47, 0x30, 0xef, 0x75, 0x2b, 0x4e, 0x7b, 0xed, 0x43, 0xb1, - 0x6e, 0x6a, 0x36, 0xee, 0x62, 0x33, 0x0e, 0x83, 0x55, 0x20, 0x6b, 0x08, 0x38, 0x6a, 0x34, 0xe1, - 0x10, 0x07, 0x62, 0xde, 0xa1, 0xdf, 0x84, 0x05, 0xdf, 0x83, 0xe3, 0xf4, 0x44, 0xe7, 0x21, 0x6b, - 0xe2, 0x7d, 0x65, 0x30, 0x70, 0xa2, 0x0d, 0x19, 0x13, 0xef, 0xd3, 0xe1, 0xaa, 0x6c, 0x41, 0x61, - 0x1d, 0x77, 0xb0, 0x8b, 0x63, 0xf3, 0xa9, 0xdb, 0x30, 0x27, 0x10, 0xe3, 0x1c, 0x9e, 0x2f, 0x24, - 0x40, 0x1c, 0x97, 0x6c, 0x07, 0x31, 0x8c, 0xd0, 0x25, 0xb2, 0xd7, 0xb9, 0x7d, 0xdb, 0x64, 0x9b, - 0x96, 0x7f, 0x8a, 0x02, 0x2b, 0xa0, 0xfb, 0xd6, 0xc0, 0x3d, 0xa6, 0x46, 0xdd, 0x23, 0xeb, 0xf3, - 0x83, 0x54, 0x26, 0x51, 0x4c, 0x56, 0xf6, 0xe1, 0x64, 0xa0, 0x85, 0x71, 0x0e, 0xe5, 0x6b, 0x90, - 0xa2, 0xad, 0x4c, 0xac, 0x24, 0xaf, 0xe6, 0xd7, 0x66, 0xbf, 0x7e, 0x59, 0x4e, 0x3e, 0xc4, 0x87, - 0x32, 0x15, 0x56, 0x9a, 0x90, 0x6b, 0x68, 0xaa, 0x19, 0xd7, 0x10, 0xf2, 0xee, 0x7c, 0x2e, 0x41, - 0x9e, 0xc1, 0xc6, 0xd9, 0x91, 0x5b, 0x90, 0xb2, 0xad, 0x7d, 0xd6, 0x91, 0xdc, 0x8d, 0xd7, 0x42, - 0x20, 0x1e, 0xe2, 0x43, 0xbf, 0x2b, 0xa1, 0xd5, 0x2b, 0x9f, 0x02, 0x92, 0xf1, 0x0b, 0x6c, 0x3b, - 0xf8, 0x5b, 0xe8, 0xe9, 0x9f, 0x4a, 0x70, 0x32, 0x80, 0xfe, 0x7f, 0xa0, 0xc3, 0xbf, 0x05, 0x67, - 0x6a, 0x6d, 0xac, 0xed, 0xd5, 0x2c, 0xd3, 0x31, 0x1c, 0x17, 0x9b, 0xda, 0x61, 0x0c, 0x73, 0xfe, - 0x3c, 0x64, 0xf7, 0x0d, 0xb7, 0xad, 0xe8, 0xc6, 0xee, 0x2e, 0xf5, 0x08, 0x62, 0x3e, 0x67, 0x88, - 0x78, 0xdd, 0xd8, 0xdd, 0xe5, 0xab, 0x58, 0x81, 0xd2, 0xe8, 0xe3, 0xe3, 0x5c, 0xcf, 0x9f, 0xc0, - 0x99, 0x35, 0xdc, 0x32, 0x4c, 0x3f, 0x05, 0x8d, 0xcb, 0x05, 0x29, 0x50, 0x1a, 0xc5, 0x8e, 0xb3, - 0xf1, 0x9f, 0x27, 0xe1, 0xd4, 0x86, 0xa9, 0xc7, 0xda, 0x76, 0xe2, 0x68, 0x34, 0xab, 0xdb, 0x35, - 0xdc, 0xc0, 0xc0, 0x70, 0x19, 0xba, 0x0d, 0x19, 0x1d, 0xab, 0xba, 0xc7, 0xd3, 0x72, 0x37, 0x5e, - 0xf7, 0x41, 0x93, 0x43, 0x4b, 0xb5, 0xdd, 0xd1, 0xaa, 0x4d, 0x71, 0xb8, 0x91, 0xbd, 0xea, 0xe8, - 0xd7, 0xe1, 0x8c, 0x61, 0xba, 0xd8, 0x36, 0xd5, 0x8e, 0xc2, 0xd0, 0x14, 0xd7, 0x36, 0x5a, 0x2d, - 0x6c, 0x73, 0x82, 0x7f, 0x35, 0xa4, 0x91, 0x75, 0xae, 0x51, 0xa3, 0x0a, 0x4d, 0x56, 0x5f, 0x3e, - 0x65, 0x84, 0x89, 0xd1, 0x1d, 0xc8, 0x93, 0x02, 0xd3, 0xa5, 0xc7, 0x06, 0x72, 0x00, 0x48, 0x8e, - 0xeb, 0x3b, 0xeb, 0x59, 0x8e, 0xa9, 0x10, 0x89, 0x83, 0x6e, 0x12, 0x67, 0xfc, 0xbc, 0x6f, 0xd8, - 0x58, 0x79, 0xa7, 0xa7, 0x95, 0x66, 0xa8, 0x05, 0x10, 0xa9, 0xf7, 0xea, 0x65, 0x19, 0x64, 0x56, - 0xf4, 0xce, 0x56, 0x8d, 0xb8, 0x66, 0xf6, 0xbd, 0xa7, 0xf1, 0xd1, 0xfe, 0x0b, 0x09, 0x4e, 0x0f, - 0x0f, 0x46, 0xbc, 0x7c, 0xbe, 0x68, 0x99, 0x58, 0xe9, 0xb5, 0x55, 0x07, 0x73, 0xfb, 0x05, 0xb6, - 0x82, 0x39, 0xcb, 0xc4, 0x5b, 0xa4, 0x90, 0xd9, 0x84, 0xf9, 0x94, 0x07, 0xa9, 0x4c, 0xb2, 0x98, - 0xaa, 0x7c, 0x06, 0x0b, 0x77, 0xf5, 0xae, 0x61, 0x36, 0x7a, 0x1d, 0x23, 0x0e, 0x56, 0x71, 0x11, - 0xb2, 0x0e, 0x81, 0x22, 0x5b, 0x16, 0x9d, 0x26, 0xbe, 0xbd, 0x20, 0x43, 0x4b, 0x1e, 0xe2, 0x43, - 0x6e, 0x97, 0x1f, 0x00, 0xf2, 0x3f, 0x3b, 0xce, 0xf9, 0xdf, 0xe4, 0xdd, 0x7a, 0x8c, 0xed, 0x56, - 0x7c, 0xcc, 0x41, 0x34, 0x98, 0xa3, 0xc6, 0xd9, 0xe0, 0xdf, 0x93, 0xe0, 0x2c, 0xc5, 0xa6, 0xb3, - 0x64, 0x17, 0xdb, 0xf4, 0x00, 0x1d, 0xc3, 0x80, 0x5c, 0x81, 0x19, 0x57, 0xb5, 0x5b, 0x98, 0x2d, - 0xda, 0xf4, 0xda, 0x3c, 0xa9, 0xf1, 0xf5, 0xcb, 0xf2, 0x6c, 0xc3, 0xb5, 0x6c, 0x5c, 0x5f, 0x97, - 0x79, 0x31, 0xef, 0xa2, 0x0a, 0x4b, 0x61, 0xcd, 0x88, 0xb3, 0xab, 0xff, 0x2d, 0xf1, 0x67, 0xd4, - 0xda, 0x8c, 0x86, 0xf4, 0x3a, 0x86, 0xa6, 0x3a, 0x31, 0xf4, 0xf5, 0x21, 0xe4, 0x34, 0x8a, 0xa9, - 0xb8, 0x87, 0x3d, 0x46, 0x28, 0xe7, 0x6e, 0x5c, 0x0c, 0x6d, 0x23, 0x7d, 0x26, 0x6b, 0x40, 0xf3, - 0xb0, 0x27, 0x76, 0x36, 0xd0, 0x3c, 0x09, 0x5a, 0x87, 0x59, 0x66, 0x19, 0xc2, 0xbc, 0x88, 0xb7, - 0x18, 0x03, 0x44, 0xd6, 0x74, 0x93, 0x56, 0x16, 0x97, 0x0a, 0x5c, 0x95, 0x5b, 0x75, 0x07, 0x5e, - 0x0b, 0xed, 0x71, 0xdc, 0xfc, 0x93, 0xf2, 0xba, 0x47, 0x96, 0xb5, 0xd7, 0xef, 0xc5, 0x60, 0xce, - 0x0b, 0x00, 0x5d, 0xf5, 0x40, 0xa1, 0xb7, 0x1b, 0x0e, 0x9f, 0x3e, 0xfc, 0x88, 0xd0, 0x55, 0x0f, - 0xe8, 0xb3, 0x1c, 0xb4, 0x0c, 0xb3, 0x36, 0x63, 0x26, 0x01, 0x9f, 0x23, 0x84, 0x1e, 0x8d, 0x21, - 0xce, 0xe6, 0x7f, 0x08, 0x8d, 0xf1, 0x37, 0x31, 0x4e, 0x2f, 0x78, 0x07, 0x66, 0xbc, 0x96, 0x26, - 0x8f, 0x74, 0xa9, 0xc5, 0xf5, 0xd0, 0x36, 0x2c, 0xf4, 0x6c, 0xbc, 0x8b, 0x5d, 0xad, 0x8d, 0x75, - 0xd1, 0xed, 0xe4, 0x11, 0xc1, 0x8a, 0x03, 0x08, 0x66, 0xa1, 0xca, 0x1f, 0x4a, 0x70, 0xf2, 0x3e, - 0x56, 0x6d, 0x77, 0x07, 0xab, 0x6e, 0xf3, 0x20, 0x8e, 0x9d, 0xf8, 0x16, 0x24, 0x4d, 0x6b, 0x9f, - 0x1f, 0x75, 0xc7, 0x6f, 0xb3, 0xbc, 0x59, 0xa4, 0x3e, 0x9f, 0x8c, 0x9f, 0xc2, 0x62, 0xb0, 0x39, - 0x71, 0xce, 0xc2, 0x9f, 0x24, 0x21, 0xbb, 0x59, 0x8b, 0xa1, 0x8b, 0xef, 0xf3, 0xf3, 0x44, 0xb4, - 0xfd, 0xbd, 0xc7, 0x54, 0x37, 0x6b, 0x0f, 0xf1, 0xa1, 0x20, 0xa7, 0x44, 0x0b, 0xdd, 0x85, 0xac, - 0xdb, 0xb6, 0xb1, 0xd3, 0xb6, 0x3a, 0x3a, 0xe7, 0x10, 0x53, 0x99, 0x69, 0xa0, 0x85, 0x3a, 0x70, - 0xca, 0x3d, 0x30, 0x29, 0x5f, 0x50, 0x5a, 0x9a, 0x32, 0x80, 0x4b, 0x4f, 0x03, 0xb7, 0xc4, 0x99, - 0x01, 0x6a, 0x1e, 0x98, 0xa4, 0x87, 0x9b, 0xb5, 0xa6, 0x00, 0x90, 0x91, 0xcb, 0x65, 0x9a, 0x27, - 0x5b, 0xda, 0x83, 0x34, 0xed, 0x05, 0x3a, 0x0b, 0x49, 0xb2, 0x75, 0x4a, 0xc1, 0xad, 0x93, 0xc8, - 0x68, 0xa7, 0xc4, 0x03, 0x8e, 0x32, 0xf6, 0x03, 0x2d, 0x36, 0x03, 0xf8, 0x3c, 0xf8, 0x10, 0x80, - 0x98, 0x30, 0xce, 0xd1, 0xff, 0x87, 0x24, 0xcc, 0x6d, 0xf5, 0x9d, 0x76, 0x3c, 0xb3, 0xbc, 0x06, - 0xd0, 0xeb, 0x3b, 0x6d, 0x6c, 0x2b, 0xee, 0x81, 0xc9, 0x3b, 0x3c, 0xe1, 0x92, 0x58, 0xf4, 0x98, - 0xe9, 0x35, 0x0f, 0x4c, 0xf4, 0x94, 0x83, 0x60, 0x65, 0x70, 0xd3, 0xfc, 0xa6, 0x0f, 0x84, 0xdf, - 0xd3, 0x57, 0xd9, 0x05, 0x7d, 0x55, 0xdc, 0xd3, 0x57, 0x9b, 0x07, 0xe6, 0x63, 0xec, 0xaa, 0x01, - 0x40, 0x4c, 0x00, 0xdf, 0x87, 0x59, 0xf2, 0x43, 0x71, 0xad, 0xa3, 0x4c, 0xac, 0x19, 0xa2, 0xd3, - 0xb4, 0xc4, 0xca, 0x4d, 0x1f, 0x6d, 0xe5, 0x92, 0xa1, 0x67, 0x0f, 0x25, 0xfb, 0xda, 0x0c, 0xdd, - 0xd7, 0xc2, 0x2c, 0xc1, 0x6d, 0xef, 0xdb, 0xd1, 0x32, 0xf4, 0xb9, 0x64, 0x3f, 0x5b, 0x82, 0xf4, - 0xae, 0x65, 0x6b, 0xb8, 0x34, 0xeb, 0xbf, 0xea, 0xa2, 0x22, 0xcf, 0x49, 0x67, 0x8a, 0xd9, 0xca, - 0x5f, 0x4a, 0x30, 0xef, 0x8d, 0x61, 0x9c, 0x0e, 0xba, 0x16, 0x18, 0x89, 0xa3, 0x0f, 0x27, 0xb1, - 0x7e, 0xe5, 0xaf, 0x13, 0x30, 0xff, 0x61, 0x1f, 0xdb, 0x87, 0xf1, 0x4c, 0xb1, 0x35, 0x16, 0x80, - 0x48, 0x1c, 0x73, 0x5a, 0xd0, 0x90, 0xc4, 0x5b, 0x30, 0xbf, 0xaf, 0x1a, 0xae, 0xb2, 0x6b, 0xd9, - 0x4a, 0xbf, 0xa7, 0xab, 0x6e, 0xf0, 0x9e, 0xba, 0x40, 0x0a, 0xef, 0x59, 0xf6, 0x36, 0x2d, 0x42, - 0x18, 0xd0, 0x9e, 0x69, 0xed, 0x9b, 0x0a, 0x11, 0x1b, 0x66, 0x8b, 0x18, 0xc3, 0x29, 0xa5, 0xe8, - 0xad, 0xc9, 0xf7, 0xfe, 0xfd, 0x65, 0xf9, 0x66, 0xcb, 0x70, 0xdb, 0xfd, 0x9d, 0xaa, 0x66, 0x75, - 0x57, 0xbd, 0xe6, 0xe8, 0x3b, 0xab, 0x21, 0x31, 0xa0, 0x7e, 0xdf, 0xd0, 0xab, 0xdb, 0xdb, 0xf5, - 0x75, 0xb9, 0x48, 0x21, 0x9f, 0x31, 0xc4, 0xe6, 0x81, 0x29, 0x78, 0xc7, 0xd7, 0x12, 0x14, 0x07, - 0xd6, 0x8a, 0x73, 0x30, 0x37, 0x20, 0xf7, 0xbc, 0x8f, 0x6d, 0x03, 0xeb, 0x47, 0x1e, 0x4d, 0xe0, - 0x8a, 0x64, 0x31, 0x7d, 0x02, 0xf9, 0x80, 0x1d, 0x92, 0xdf, 0xcc, 0x0e, 0xb9, 0xfd, 0x81, 0x09, - 0x2a, 0x9f, 0x27, 0x60, 0x51, 0xc6, 0x8e, 0xd5, 0x79, 0x81, 0xeb, 0xf4, 0x20, 0x17, 0xc3, 0x7c, - 0x79, 0x0a, 0xc0, 0xcf, 0x91, 0xdf, 0x64, 0xda, 0x64, 0x19, 0x06, 0x31, 0xc0, 0x1a, 0xcc, 0x38, - 0xae, 0xea, 0xf6, 0xd9, 0xf5, 0x5e, 0x38, 0x5b, 0xf5, 0x99, 0xb0, 0x41, 0xeb, 0x0a, 0x9f, 0xc2, - 0x34, 0xc9, 0xb9, 0xbc, 0x67, 0x19, 0x8e, 0x65, 0x06, 0x2f, 0x00, 0x99, 0x8c, 0xcf, 0x84, 0x5f, - 0x85, 0x53, 0x43, 0xb6, 0x88, 0xd3, 0xef, 0xff, 0x71, 0x02, 0xce, 0x06, 0xe1, 0x63, 0xba, 0x02, - 0xfd, 0x7f, 0x6b, 0xef, 0x39, 0xc8, 0x3f, 0xb1, 0x2c, 0x8f, 0xe2, 0x56, 0x0a, 0x90, 0x63, 0xbf, - 0xa9, 0x49, 0xc8, 0x31, 0x2b, 0xcc, 0x5e, 0x31, 0x9f, 0x28, 0xf3, 0x31, 0x1d, 0x7f, 0x8f, 0x17, - 0x5c, 0xe1, 0x96, 0x68, 0x42, 0xe1, 0x5b, 0x38, 0x2f, 0xff, 0x44, 0x02, 0xd4, 0xb4, 0xfb, 0xa6, - 0xa6, 0xba, 0xf8, 0x91, 0xd5, 0x8a, 0xa1, 0x8f, 0x4b, 0x90, 0x36, 0x4c, 0x1d, 0x1f, 0xd0, 0x3e, - 0xa6, 0x44, 0x4f, 0xa8, 0x08, 0xdd, 0x82, 0x0c, 0x0f, 0x0d, 0xb3, 0x48, 0x51, 0xd2, 0xe3, 0x77, - 0xb3, 0x2c, 0x18, 0xbc, 0xfe, 0xf5, 0xe0, 0xab, 0x3c, 0xcb, 0xe2, 0xc1, 0x22, 0x8c, 0xf6, 0x09, - 0x9c, 0x0c, 0xb4, 0x34, 0x4e, 0x33, 0xfc, 0x13, 0xbd, 0x18, 0xa6, 0x7d, 0x8f, 0xeb, 0xc2, 0xe0, - 0x58, 0xc1, 0x7d, 0xf4, 0x01, 0x40, 0xcf, 0xc6, 0x2f, 0x14, 0xa6, 0x9a, 0x9c, 0x4a, 0x35, 0x4b, - 0x34, 0xa8, 0x80, 0x5b, 0xea, 0x9f, 0x25, 0x58, 0x8c, 0xfb, 0xfe, 0xe3, 0x3b, 0xec, 0x4e, 0x03, - 0x8a, 0xf4, 0x67, 0xdd, 0xdc, 0xb5, 0x62, 0xbb, 0x83, 0xfa, 0x23, 0x09, 0x16, 0x7c, 0xa8, 0x71, - 0xee, 0xe9, 0xc7, 0x4b, 0xeb, 0xf8, 0x94, 0xec, 0xb2, 0xfe, 0x19, 0x18, 0xe7, 0xfc, 0xfe, 0xfd, - 0x04, 0x9c, 0xae, 0x59, 0xdd, 0x5e, 0xdf, 0xc5, 0xf4, 0xb6, 0xdf, 0xe9, 0x77, 0x63, 0x98, 0x13, - 0xcb, 0x30, 0xfb, 0x02, 0xdb, 0x8e, 0x61, 0xb1, 0x2d, 0xa5, 0x20, 0xee, 0x2c, 0xb8, 0x10, 0xfd, - 0x06, 0xe4, 0x34, 0xfe, 0x34, 0xb1, 0xe2, 0xf3, 0x6b, 0x75, 0x52, 0xe7, 0x98, 0xc4, 0xe4, 0xd5, - 0xcb, 0x32, 0x88, 0xf6, 0xd7, 0xd7, 0x65, 0x10, 0xe8, 0x75, 0x1d, 0xad, 0x40, 0xc6, 0x31, 0xd5, - 0x9e, 0xd3, 0xb6, 0x82, 0x97, 0xb6, 0x9e, 0x94, 0x8f, 0xfb, 0x0f, 0xe1, 0xcc, 0x88, 0x21, 0xe2, - 0xb4, 0xf4, 0x0e, 0x94, 0xd7, 0x71, 0xcf, 0xc6, 0xc4, 0x4d, 0xe9, 0x1f, 0x61, 0xdb, 0xd8, 0x3d, - 0x8c, 0xcf, 0xe2, 0xbc, 0x0f, 0x2d, 0x58, 0x89, 0x7e, 0x46, 0x9c, 0x9d, 0xf9, 0xd9, 0x2c, 0x14, - 0x36, 0x0e, 0x7a, 0x96, 0xed, 0x36, 0x18, 0x41, 0x40, 0x0f, 0x20, 0xd3, 0xb3, 0xad, 0x17, 0x86, - 0x00, 0x9e, 0x0b, 0x8d, 0x29, 0x04, 0x74, 0xb6, 0x78, 0x7d, 0xef, 0x24, 0xc5, 0x7f, 0x23, 0x19, - 0xb2, 0x8f, 0x2c, 0x4d, 0xed, 0xdc, 0x33, 0x3a, 0x62, 0xad, 0x54, 0x27, 0x81, 0x55, 0x3d, 0x8d, - 0x2d, 0xd5, 0x6d, 0x0b, 0x8f, 0xe1, 0x09, 0xd1, 0x26, 0x64, 0xee, 0xbb, 0x6e, 0x8f, 0x14, 0x72, - 0x77, 0x73, 0x69, 0x22, 0x24, 0x51, 0x10, 0x8d, 0x13, 0xca, 0x48, 0x86, 0x85, 0x4d, 0xcb, 0x6a, - 0x75, 0x70, 0xad, 0x63, 0xf5, 0xf5, 0x9a, 0x65, 0xee, 0x1a, 0x2d, 0x7e, 0x50, 0xbd, 0x38, 0x11, - 0x71, 0xb3, 0xd6, 0x90, 0x47, 0xd5, 0xd1, 0xf7, 0x21, 0xd3, 0xb8, 0xc9, 0xa1, 0xd8, 0xc9, 0xf5, - 0xc2, 0x44, 0xa8, 0xc6, 0x4d, 0xd9, 0x53, 0x42, 0xf7, 0x21, 0x77, 0xf7, 0xb3, 0xbe, 0x8d, 0x39, - 0xc6, 0x0c, 0xc5, 0xb8, 0x3c, 0x11, 0x83, 0xea, 0xc8, 0x7e, 0xd5, 0xa5, 0x55, 0x28, 0x04, 0x2c, - 0x89, 0x4a, 0x90, 0xea, 0x11, 0xa3, 0x91, 0x41, 0xcd, 0x8a, 0x3b, 0x20, 0x22, 0x61, 0x73, 0x6e, - 0xe9, 0x2d, 0x48, 0x11, 0xdb, 0x90, 0x35, 0xbf, 0xa3, 0x3a, 0x78, 0xdb, 0x36, 0x02, 0x55, 0x85, - 0x90, 0xd7, 0xfe, 0x1b, 0x09, 0x12, 0x8d, 0x9b, 0x84, 0xe1, 0xed, 0xf4, 0xb5, 0x3d, 0xec, 0x06, - 0xea, 0x72, 0x19, 0xe5, 0x7f, 0x36, 0xde, 0x35, 0x18, 0x55, 0xf0, 0x4a, 0x99, 0x0c, 0x5d, 0x00, - 0x50, 0x35, 0x0d, 0x3b, 0x0e, 0x0d, 0x81, 0x24, 0x7d, 0x35, 0xb2, 0x4c, 0xfe, 0x10, 0x1f, 0x12, - 0x08, 0x07, 0x6b, 0x36, 0x66, 0x6b, 0xde, 0x83, 0x60, 0x32, 0x02, 0xe1, 0xe2, 0x6e, 0x4f, 0x71, - 0xad, 0x3d, 0x6c, 0x52, 0x8b, 0x7b, 0x10, 0x44, 0xde, 0x24, 0x62, 0xde, 0xe0, 0x4d, 0x48, 0x6e, - 0xd6, 0x1a, 0xdf, 0xa4, 0xc1, 0x1c, 0xe8, 0x47, 0x12, 0xa4, 0xa9, 0xa1, 0x51, 0x05, 0xb2, 0x9a, - 0x65, 0xba, 0xaa, 0x61, 0xf2, 0xb5, 0xe2, 0x3d, 0xdc, 0x13, 0x4f, 0x30, 0xc1, 0x15, 0xc8, 0xab, - 0x9a, 0x66, 0xf5, 0x4d, 0x57, 0x31, 0xd5, 0x2e, 0x0e, 0x18, 0x21, 0xc7, 0x4b, 0x9e, 0xa8, 0x5d, - 0x8c, 0x2e, 0x81, 0xf8, 0x49, 0x8d, 0xe5, 0xb7, 0x05, 0xf0, 0x02, 0x2f, 0x5c, 0xc4, 0x7d, 0xc8, - 0x5f, 0x49, 0xb0, 0xf0, 0xcc, 0x36, 0x5c, 0xbc, 0xa6, 0xba, 0x5a, 0x3b, 0x86, 0xcd, 0xe0, 0x3d, - 0xc8, 0xea, 0xaa, 0xab, 0xb2, 0x7c, 0xc2, 0xc4, 0x78, 0x6d, 0xbe, 0xd8, 0x48, 0x7d, 0x9a, 0x53, - 0x88, 0x20, 0x45, 0xbe, 0xb3, 0x1d, 0x42, 0xa6, 0xdf, 0x07, 0xa1, 0x22, 0x7f, 0x2b, 0xe3, 0x74, - 0x6e, 0xff, 0x2a, 0x09, 0xe7, 0x16, 0x43, 0xef, 0xef, 0xc0, 0x2c, 0x3f, 0x43, 0xf1, 0xbe, 0xaf, - 0x4c, 0x5a, 0x95, 0x62, 0xe1, 0x70, 0x35, 0xb4, 0x06, 0xe0, 0xb8, 0xaa, 0xed, 0x2a, 0xae, 0xd1, - 0x9d, 0x2e, 0xf2, 0x2b, 0xa6, 0x13, 0x55, 0x23, 0xd2, 0xc1, 0xd0, 0x16, 0xd6, 0xfa, 0x9d, 0xbd, - 0xa7, 0xbd, 0x46, 0xbf, 0xdb, 0x55, 0xed, 0x43, 0x74, 0x5e, 0x8c, 0x8d, 0xf1, 0x19, 0xa6, 0x7d, - 0x4b, 0x06, 0x86, 0xc0, 0xf8, 0x0c, 0x93, 0xf5, 0xcf, 0xb3, 0x17, 0x06, 0xa5, 0x54, 0x82, 0xde, - 0x80, 0x02, 0x65, 0xef, 0x0a, 0x36, 0x5d, 0xdb, 0xc0, 0x0e, 0x67, 0xee, 0xac, 0x4a, 0x9e, 0x16, - 0x6d, 0xb0, 0x12, 0x74, 0x0d, 0xe6, 0x9c, 0x43, 0xc7, 0xc5, 0x5d, 0x85, 0xe5, 0xd3, 0xb2, 0x44, - 0x2f, 0x51, 0xb7, 0xc0, 0xca, 0x64, 0x56, 0x54, 0xf9, 0xb7, 0x04, 0xcc, 0x09, 0xfb, 0xc7, 0x49, - 0xbf, 0xd6, 0x20, 0xbd, 0x6b, 0x74, 0xbc, 0xf8, 0x45, 0xb4, 0x7b, 0x14, 0x48, 0x55, 0xe2, 0x04, - 0xbd, 0x8b, 0x3c, 0xa2, 0xba, 0xf4, 0xb7, 0x12, 0xa4, 0xe8, 0x7e, 0xf2, 0x0e, 0xa4, 0xe8, 0x84, - 0x96, 0xa6, 0x99, 0xd0, 0xb4, 0xaa, 0xe7, 0x49, 0x13, 0xc3, 0x9e, 0x14, 0x9d, 0x86, 0x19, 0xa7, - 0xad, 0xde, 0x7a, 0xe7, 0x06, 0xf5, 0x45, 0x79, 0x99, 0xff, 0x42, 0x6b, 0x90, 0xc1, 0xb4, 0x45, - 0x58, 0xe7, 0x3e, 0x3d, 0x6c, 0xf6, 0x04, 0x86, 0x54, 0x8c, 0x9f, 0xd0, 0x63, 0x91, 0xa1, 0x07, - 0xa9, 0x4c, 0xaa, 0x98, 0xae, 0x7c, 0x95, 0x84, 0x42, 0xbd, 0x1b, 0xd3, 0xcc, 0xbe, 0x1b, 0x34, - 0x67, 0xd8, 0x76, 0x1a, 0x78, 0xd6, 0xa8, 0x35, 0x83, 0xae, 0x21, 0x79, 0x34, 0xd7, 0x50, 0x87, - 0x19, 0x1b, 0xf3, 0x64, 0x63, 0xf2, 0xfc, 0x6b, 0x13, 0x9f, 0xdf, 0x54, 0x77, 0x3a, 0x58, 0x26, - 0x3a, 0x5e, 0x5c, 0x8a, 0x02, 0x2c, 0xfd, 0x36, 0x1f, 0xd3, 0x77, 0x21, 0xa9, 0x1b, 0xc2, 0x12, - 0xd3, 0xae, 0x53, 0xa2, 0x32, 0xd5, 0xd0, 0xa6, 0xfc, 0x43, 0xeb, 0x0f, 0xdb, 0x2d, 0x35, 0x00, - 0x06, 0x6d, 0x43, 0x17, 0x61, 0xc6, 0xea, 0xe8, 0x84, 0x17, 0x4b, 0x94, 0x3b, 0x17, 0xf8, 0x49, - 0x38, 0xfd, 0xb4, 0xa3, 0xd7, 0xd7, 0xe5, 0xb4, 0xd5, 0xd1, 0xeb, 0x3a, 0x3a, 0x0b, 0x19, 0x13, - 0xef, 0x2b, 0x34, 0xc9, 0x9c, 0xa6, 0x01, 0xc8, 0xb3, 0x26, 0xde, 0x5f, 0xc7, 0x8e, 0xe6, 0xf7, - 0xe6, 0x7c, 0xdc, 0x7f, 0x24, 0xc1, 0x9c, 0xb0, 0x45, 0xbc, 0x2b, 0x2a, 0x63, 0x74, 0xf9, 0xfc, - 0x4c, 0x1e, 0x6d, 0x7e, 0x0a, 0x3d, 0x9e, 0x80, 0xf5, 0x11, 0x9c, 0x64, 0xa9, 0x0a, 0x9a, 0xea, - 0xba, 0xd8, 0x8e, 0x8d, 0x11, 0xff, 0x97, 0x04, 0x8b, 0x41, 0xe0, 0x38, 0xfb, 0xff, 0x70, 0x28, - 0x24, 0xfa, 0x76, 0x08, 0x48, 0xd8, 0xd3, 0x59, 0x68, 0x33, 0x18, 0x1d, 0x5d, 0xba, 0x03, 0x69, - 0x2a, 0x3e, 0x86, 0x6b, 0xe1, 0x46, 0x6c, 0xc3, 0xc2, 0x5d, 0x5d, 0x6f, 0x34, 0xf8, 0x64, 0xfa, - 0xc6, 0x2b, 0x5c, 0xec, 0xbe, 0x89, 0xb0, 0xdd, 0xd7, 0xff, 0xa4, 0x38, 0x77, 0xdf, 0x7f, 0x5c, - 0x84, 0x3c, 0x6f, 0xfb, 0xb6, 0x49, 0x0e, 0x8b, 0xab, 0x90, 0x6c, 0x71, 0xde, 0x15, 0xdc, 0xf8, - 0xbc, 0x38, 0xa5, 0xf7, 0x3e, 0x80, 0x4c, 0x6a, 0x12, 0x85, 0x5e, 0xdf, 0x0d, 0x09, 0xe0, 0x0d, - 0xa2, 0x38, 0x03, 0x85, 0x5e, 0xdf, 0x45, 0x1f, 0xc2, 0xbc, 0x36, 0xc8, 0xc3, 0x56, 0x88, 0x72, - 0x32, 0x32, 0x2d, 0x2a, 0x34, 0x29, 0x5d, 0x9e, 0xd3, 0x02, 0x62, 0x74, 0xd7, 0x9f, 0xfc, 0x9b, - 0x8a, 0xa4, 0xf4, 0xc3, 0xf9, 0xc6, 0xbe, 0xdc, 0x60, 0xf4, 0x2e, 0xcc, 0xe8, 0x34, 0x99, 0x94, - 0x1f, 0x09, 0xc2, 0x96, 0x56, 0x20, 0x73, 0x57, 0xe6, 0xf5, 0xd1, 0x7d, 0xc8, 0xb3, 0x6f, 0x2c, - 0xc6, 0xce, 0xb7, 0x8e, 0x4b, 0xd1, 0xfa, 0xbe, 0xcb, 0x64, 0x39, 0xa7, 0x0f, 0x64, 0xe8, 0x06, - 0xa4, 0x1c, 0x4d, 0x35, 0x69, 0x48, 0x2b, 0x3c, 0xfc, 0xe0, 0x4b, 0xc6, 0x94, 0x69, 0x5d, 0xf4, - 0x0c, 0x16, 0x76, 0x70, 0xcb, 0x30, 0x15, 0x77, 0x70, 0xcd, 0x5b, 0xca, 0x8c, 0xdc, 0x2c, 0x7b, - 0xde, 0x21, 0x3c, 0x07, 0x50, 0x2e, 0xee, 0x0c, 0x15, 0x90, 0x61, 0xc2, 0xa6, 0x1e, 0x80, 0xcd, - 0x46, 0x0e, 0x53, 0x68, 0x72, 0x9e, 0x3c, 0x87, 0x03, 0x62, 0xb4, 0x01, 0x39, 0x95, 0xac, 0x4f, - 0x85, 0x66, 0x4e, 0x95, 0x20, 0xf2, 0x18, 0x37, 0x92, 0xc3, 0x25, 0x83, 0xea, 0x89, 0x06, 0x30, - 0x5d, 0x6c, 0xb7, 0x70, 0x29, 0x37, 0x1e, 0xc6, 0x7f, 0x69, 0xcc, 0x61, 0xa8, 0x08, 0x3d, 0x84, - 0x42, 0x5b, 0x24, 0x0e, 0xd0, 0xfb, 0xf8, 0x7c, 0xe4, 0x39, 0x2e, 0x24, 0xdf, 0x41, 0xce, 0xb7, - 0x7d, 0x42, 0xf4, 0x16, 0x24, 0x5a, 0x5a, 0xa9, 0x40, 0x11, 0xce, 0x8d, 0x8b, 0xee, 0xcb, 0x89, - 0x96, 0x86, 0xde, 0x87, 0x0c, 0x8b, 0x7f, 0x1e, 0x98, 0xa5, 0xb9, 0xc8, 0xc5, 0x1b, 0x0c, 0x3d, - 0xcb, 0x34, 0x4e, 0x4b, 0x9e, 0x75, 0x1f, 0xf2, 0xec, 0xfa, 0xb6, 0x43, 0xf3, 0x4e, 0x4a, 0xf3, - 0x91, 0x13, 0x6e, 0x34, 0x81, 0x46, 0x66, 0x2f, 0x05, 0x31, 0x19, 0x7a, 0x02, 0x73, 0x36, 0xbb, - 0xb7, 0x57, 0x58, 0x4c, 0xa1, 0x54, 0xa4, 0x58, 0x57, 0xc2, 0x5d, 0xc9, 0x48, 0xec, 0x49, 0x2e, - 0xd8, 0x7e, 0x29, 0xfa, 0x21, 0x2c, 0x06, 0xf1, 0xf8, 0x92, 0x58, 0xa0, 0xa8, 0x6f, 0x4d, 0x44, - 0xf5, 0xaf, 0x0c, 0x64, 0x8f, 0x14, 0xa1, 0x5b, 0x90, 0x66, 0x63, 0x8e, 0x28, 0x60, 0x39, 0x04, - 0x30, 0x30, 0xdc, 0xac, 0x36, 0x31, 0x98, 0xcb, 0xaf, 0xac, 0x95, 0x8e, 0xd5, 0x2a, 0x9d, 0x8c, - 0x34, 0xd8, 0xe8, 0x1d, 0xbc, 0x9c, 0x73, 0x07, 0x32, 0x32, 0x67, 0x6c, 0x26, 0xe7, 0x77, 0xa9, - 0x8b, 0x91, 0x73, 0x26, 0xe4, 0x1e, 0x5b, 0xce, 0xdb, 0x3e, 0x21, 0x1d, 0x47, 0x96, 0x56, 0xa4, - 0xd0, 0x65, 0x7f, 0x2a, 0x7a, 0x1c, 0x47, 0x52, 0xb1, 0xe5, 0x9c, 0x3d, 0x90, 0xa1, 0x26, 0x14, - 0x35, 0x76, 0x9b, 0xa6, 0x88, 0xbb, 0xb8, 0xd2, 0x69, 0x8a, 0xf6, 0x46, 0xa8, 0x4f, 0x0d, 0xbb, - 0x81, 0x94, 0xe7, 0xb5, 0xa0, 0x1c, 0xf5, 0x60, 0x49, 0xf7, 0xee, 0xb7, 0x94, 0x17, 0xf4, 0x82, - 0x6b, 0x80, 0x7f, 0x86, 0xe2, 0xdf, 0x08, 0x75, 0x73, 0x63, 0x2f, 0xde, 0xe4, 0x92, 0x1e, 0x51, - 0x81, 0x38, 0x33, 0x8a, 0xaf, 0x68, 0x83, 0x34, 0xe8, 0x52, 0x29, 0xd2, 0x99, 0x45, 0x24, 0x6c, - 0xcb, 0x45, 0x6d, 0xa8, 0x80, 0x78, 0x56, 0xd3, 0xb2, 0x7a, 0xa5, 0xb3, 0x91, 0x9e, 0xd5, 0x17, - 0xce, 0x92, 0x69, 0x5d, 0xb2, 0x48, 0x0d, 0xd3, 0x70, 0xe9, 0x06, 0xb5, 0x14, 0xb9, 0x48, 0x83, - 0xaf, 0xfc, 0xc8, 0xb3, 0x06, 0xfb, 0x4d, 0x96, 0x96, 0xcb, 0xef, 0xfe, 0xf9, 0x54, 0x39, 0x17, - 0xb9, 0xb4, 0xc2, 0x82, 0x04, 0x72, 0xc1, 0xf5, 0x4b, 0xc9, 0xd2, 0x62, 0x4e, 0x6f, 0x08, 0xf5, - 0xf5, 0xc8, 0xa5, 0x15, 0x99, 0x7f, 0x29, 0x23, 0x75, 0xa4, 0x88, 0x9c, 0x7b, 0x29, 0x20, 0x7d, - 0x5d, 0xb0, 0xb4, 0x1c, 0xb9, 0x87, 0x0e, 0x87, 0x00, 0xe4, 0x6c, 0x47, 0x48, 0x88, 0x63, 0xde, - 0xb7, 0x0d, 0x17, 0x2b, 0x3b, 0xaa, 0xab, 0xb5, 0x4b, 0xe5, 0x48, 0xc7, 0x3c, 0x72, 0xe3, 0x21, - 0xc3, 0xbe, 0x27, 0x22, 0x5b, 0x31, 0x3b, 0x4f, 0x95, 0x56, 0x26, 0x9c, 0x0d, 0xbc, 0xad, 0x98, - 0xd5, 0x47, 0xdf, 0x87, 0xec, 0xf3, 0x3e, 0xb6, 0x0f, 0xa9, 0x63, 0x3d, 0x1f, 0xf9, 0x32, 0xe8, - 0x50, 0xc6, 0x85, 0x9c, 0x79, 0xce, 0x05, 0xe4, 0xd1, 0x8c, 0x2a, 0x97, 0x2a, 0x91, 0x8f, 0x0e, - 0x1c, 0x73, 0x64, 0x5e, 0x1f, 0xa9, 0x70, 0x8a, 0x8d, 0x0f, 0x4f, 0xd9, 0xb4, 0x79, 0x56, 0x64, - 0xe9, 0x02, 0x05, 0x8a, 0xe4, 0xaa, 0xa1, 0x59, 0xa3, 0xf2, 0x49, 0x75, 0xb4, 0x8c, 0x38, 0x1f, - 0xbe, 0x7d, 0x32, 0x7e, 0x5b, 0xba, 0x18, 0xe9, 0x7c, 0x42, 0xd8, 0xbd, 0x9c, 0x57, 0x7d, 0x42, - 0xb6, 0x89, 0xea, 0x8a, 0xe3, 0xb8, 0x84, 0x54, 0x96, 0x2e, 0x8d, 0xd9, 0x44, 0x87, 0x38, 0x2e, - 0xd9, 0x44, 0xf5, 0x06, 0xd3, 0x7b, 0x2f, 0xf5, 0x25, 0x3b, 0xf7, 0xbc, 0x56, 0x3c, 0x57, 0xf9, - 0xf1, 0x22, 0x14, 0x04, 0xe1, 0x64, 0x64, 0xf2, 0xba, 0x9f, 0x4c, 0x2e, 0x47, 0x91, 0x49, 0xa6, - 0xc1, 0xd8, 0xe4, 0x75, 0x3f, 0x9b, 0x5c, 0x8e, 0x62, 0x93, 0x42, 0x83, 0xd0, 0x49, 0x39, 0x8a, - 0x4e, 0xbe, 0x31, 0x05, 0x9d, 0xe4, 0x40, 0xc3, 0x7c, 0x72, 0x6d, 0x94, 0x4f, 0x5e, 0x1c, 0xcf, - 0x27, 0x39, 0x90, 0x8f, 0x50, 0xde, 0x1e, 0x22, 0x94, 0xe7, 0xc7, 0x10, 0x4a, 0xae, 0x2d, 0x18, - 0x65, 0x3d, 0x94, 0x51, 0x5e, 0x9e, 0xc4, 0x28, 0x39, 0x4a, 0x80, 0x52, 0xde, 0x0c, 0x50, 0xca, - 0x72, 0x24, 0xa5, 0xe4, 0xba, 0x8c, 0x53, 0x7e, 0x1c, 0xcd, 0x29, 0xaf, 0x4d, 0xc5, 0x29, 0x39, - 0xda, 0x28, 0xa9, 0x94, 0xa3, 0x48, 0xe5, 0x1b, 0x53, 0x90, 0x4a, 0x31, 0x58, 0x43, 0xac, 0xf2, - 0x5e, 0x18, 0xab, 0xbc, 0x34, 0x81, 0x55, 0x72, 0x2c, 0x3f, 0xad, 0xbc, 0x17, 0x46, 0x2b, 0x2f, - 0x4d, 0xa0, 0x95, 0x01, 0x1c, 0xc6, 0x2b, 0x1f, 0x85, 0xf3, 0xca, 0x2b, 0x13, 0x79, 0x25, 0xc7, - 0x0a, 0x12, 0xcb, 0xb7, 0x7d, 0xc4, 0xf2, 0xf5, 0x08, 0x62, 0xc9, 0x15, 0x09, 0xb3, 0xfc, 0x60, - 0x84, 0x59, 0x56, 0xc6, 0x31, 0x4b, 0xae, 0xe9, 0x51, 0xcb, 0x7a, 0x28, 0xb5, 0xbc, 0x3c, 0x89, - 0x5a, 0x8a, 0x99, 0xe7, 0xe7, 0x96, 0x4f, 0x23, 0xb8, 0xe5, 0xd5, 0xc9, 0xdc, 0x92, 0xc3, 0x0d, - 0x91, 0x4b, 0x65, 0x2c, 0xb9, 0x7c, 0x7b, 0x4a, 0x72, 0xc9, 0xb1, 0xc3, 0xd8, 0xe5, 0x2f, 0x07, - 0xd9, 0xe5, 0x4a, 0x34, 0xbb, 0xe4, 0x20, 0x9c, 0x5e, 0xd6, 0x43, 0xe9, 0xe5, 0xe5, 0x49, 0xf4, - 0x52, 0x18, 0xcd, 0xcf, 0x2f, 0x1f, 0x85, 0xf3, 0xcb, 0x2b, 0x13, 0xf9, 0xa5, 0x98, 0x3b, 0x01, - 0x82, 0x59, 0x0f, 0x25, 0x98, 0x97, 0x27, 0x11, 0x4c, 0x6f, 0x34, 0x7d, 0x0c, 0x73, 0x3b, 0x92, - 0x61, 0xbe, 0x39, 0x0d, 0xc3, 0xe4, 0x90, 0x23, 0x14, 0xf3, 0xf9, 0x14, 0x14, 0xf3, 0xe6, 0x91, - 0x28, 0x26, 0x7f, 0x52, 0x34, 0xc7, 0xfc, 0x38, 0x9a, 0x63, 0x5e, 0x9b, 0x8a, 0x63, 0x0a, 0xe7, - 0x36, 0x42, 0x32, 0x6f, 0x06, 0x48, 0x66, 0x39, 0x92, 0x64, 0x0a, 0x5f, 0x4b, 0x59, 0xe6, 0x07, - 0x23, 0x2c, 0xb3, 0x32, 0x8e, 0x65, 0x8a, 0x05, 0x2b, 0x68, 0xa6, 0x32, 0x96, 0x16, 0xbe, 0x3d, - 0x25, 0x2d, 0x14, 0x8b, 0x22, 0x84, 0x17, 0xd6, 0x42, 0x78, 0xe1, 0xc5, 0xf1, 0xbc, 0x50, 0xec, - 0x85, 0x03, 0x62, 0x78, 0x2f, 0x8c, 0x18, 0x5e, 0x9a, 0x40, 0x0c, 0x85, 0x6b, 0xf5, 0x31, 0xc3, - 0xdb, 0x43, 0xcc, 0xf0, 0xfc, 0xc4, 0xa0, 0x82, 0x47, 0x0d, 0xef, 0x8c, 0x52, 0xc3, 0x0b, 0x63, - 0xa9, 0x21, 0xd7, 0x1f, 0x70, 0xc3, 0xdb, 0x43, 0xdc, 0xf0, 0xfc, 0x18, 0x6e, 0x28, 0x1e, 0xce, - 0xc9, 0xe1, 0xce, 0x78, 0x72, 0x58, 0x9d, 0x96, 0x1c, 0x72, 0xd8, 0x50, 0x76, 0xf8, 0x28, 0x9c, - 0x1d, 0x5e, 0x99, 0xf2, 0x92, 0x74, 0x88, 0x1e, 0xde, 0x0b, 0xa3, 0x87, 0x97, 0x26, 0xd0, 0xc3, - 0xc1, 0x66, 0x18, 0xc6, 0x0f, 0x1f, 0xa4, 0x32, 0xe7, 0x8a, 0xaf, 0x57, 0xbe, 0x4a, 0xc1, 0xcc, - 0x7d, 0x11, 0xd3, 0xf0, 0xbd, 0x01, 0x20, 0x1d, 0xe7, 0x0d, 0x00, 0xb4, 0x0e, 0xb3, 0xdc, 0x98, - 0x9c, 0x33, 0x8e, 0x79, 0xad, 0x69, 0xe4, 0xe5, 0x16, 0xa1, 0x7a, 0xcc, 0x84, 0x38, 0x74, 0x1b, - 0x0a, 0x7d, 0x07, 0xdb, 0x4a, 0xcf, 0x36, 0x2c, 0xdb, 0x70, 0x59, 0xc4, 0x57, 0x5a, 0x5b, 0xe4, - 0xef, 0xa4, 0xe5, 0xb7, 0x1d, 0x6c, 0x6f, 0xf1, 0x32, 0x39, 0xdf, 0xf7, 0xfd, 0x12, 0x7f, 0x15, - 0x93, 0x9e, 0xfe, 0xaf, 0x62, 0x9e, 0x41, 0xd1, 0xc6, 0xaa, 0x1e, 0x70, 0x5b, 0x2c, 0x75, 0x3e, - 0xdc, 0xa1, 0xab, 0xba, 0xcf, 0x37, 0xf9, 0x52, 0xe8, 0xe7, 0xed, 0x60, 0x11, 0xfa, 0x1e, 0x9c, - 0xea, 0xaa, 0x07, 0xec, 0xcd, 0x10, 0xb1, 0xf9, 0xd0, 0x48, 0x4f, 0xc6, 0x17, 0x34, 0x44, 0x5d, - 0xf5, 0x80, 0xfe, 0x07, 0x0d, 0xab, 0x40, 0xdf, 0xd4, 0xbf, 0x06, 0x73, 0xba, 0xe1, 0xb8, 0x86, - 0xa9, 0x89, 0xf7, 0x50, 0xb3, 0xfe, 0x44, 0x71, 0x51, 0xc6, 0x5e, 0x38, 0xbd, 0x0e, 0x0b, 0xfc, - 0xed, 0xff, 0xc1, 0xbf, 0xd2, 0x50, 0xae, 0x96, 0x19, 0xb4, 0x8b, 0x14, 0x0f, 0xfe, 0xd4, 0x67, - 0x13, 0xe6, 0x5b, 0xaa, 0x8b, 0xf7, 0xd5, 0x43, 0xc5, 0xb4, 0x74, 0x3a, 0x36, 0x39, 0xfa, 0xd2, - 0x56, 0x99, 0x8f, 0x4d, 0x61, 0x93, 0x15, 0x3f, 0xb1, 0x74, 0x36, 0x42, 0x33, 0xec, 0x9b, 0x5c, - 0x68, 0xf9, 0x0a, 0xf4, 0x07, 0xa9, 0xcc, 0x6c, 0x31, 0x53, 0xf9, 0x33, 0x09, 0xf2, 0x81, 0x20, - 0xfb, 0xaf, 0x0c, 0xdd, 0x9f, 0x9f, 0x0d, 0x27, 0x68, 0xe1, 0xb1, 0x88, 0xbb, 0x90, 0xe1, 0xb6, - 0x12, 0xd1, 0x88, 0x72, 0xf4, 0x1e, 0x4d, 0x0f, 0x43, 0x22, 0x14, 0x23, 0xd4, 0xde, 0x4b, 0xfd, - 0xf9, 0x17, 0xe5, 0x13, 0x95, 0x5f, 0x24, 0xa1, 0x10, 0x8c, 0xaa, 0xd7, 0x87, 0xda, 0x15, 0xb6, - 0x82, 0x03, 0x1a, 0xd1, 0xad, 0x5c, 0x87, 0xac, 0xcd, 0x2b, 0x89, 0x66, 0xae, 0x8c, 0x89, 0x12, - 0xf8, 0xdb, 0x39, 0x50, 0x5c, 0xfa, 0xfb, 0x84, 0xb7, 0x62, 0xab, 0x90, 0xa6, 0xff, 0x25, 0xc5, - 0x9b, 0x16, 0x96, 0x53, 0xb7, 0x41, 0xca, 0x65, 0x56, 0x8d, 0xac, 0xf0, 0xe6, 0xb1, 0xde, 0xf1, - 0xf1, 0x04, 0xc7, 0xf8, 0x53, 0xa5, 0x63, 0xbe, 0x94, 0xd2, 0x20, 0x07, 0xc9, 0x4e, 0x07, 0x6b, - 0x2e, 0xff, 0xff, 0x29, 0xf1, 0xa7, 0x49, 0x17, 0x87, 0x21, 0xf8, 0xbf, 0x55, 0x55, 0x65, 0xfe, - 0x6f, 0x55, 0xbe, 0x00, 0xd1, 0x9c, 0x07, 0x41, 0xa7, 0x3d, 0x8b, 0x08, 0xb2, 0xa1, 0x7e, 0xf3, - 0x11, 0x9c, 0x0c, 0x59, 0x96, 0x68, 0x0e, 0xa0, 0xf6, 0xf4, 0x49, 0xa3, 0xde, 0x68, 0x6e, 0x3c, - 0x69, 0x16, 0x4f, 0xa0, 0x02, 0x64, 0xc9, 0xef, 0x8d, 0x27, 0x8d, 0xed, 0x46, 0x51, 0x42, 0x45, - 0xc8, 0xd7, 0x9f, 0xf8, 0x2a, 0x24, 0x96, 0x52, 0x7f, 0xf0, 0xe3, 0xe5, 0x13, 0x6f, 0x3e, 0x83, - 0x9c, 0xef, 0xfd, 0x18, 0x84, 0x60, 0x6e, 0x6b, 0xbb, 0x71, 0x5f, 0x69, 0xd6, 0x1f, 0x6f, 0x34, - 0x9a, 0x77, 0x1f, 0x6f, 0x15, 0x4f, 0x10, 0x64, 0x2a, 0xbb, 0xbb, 0xf6, 0x54, 0x6e, 0x16, 0x25, - 0xef, 0x77, 0xf3, 0xe9, 0x76, 0xed, 0x7e, 0x31, 0xe1, 0xfd, 0xfe, 0x70, 0x7b, 0x43, 0xfe, 0x41, - 0x31, 0xc9, 0x81, 0x55, 0x38, 0x15, 0x9a, 0x38, 0x86, 0x72, 0x30, 0xbb, 0x6d, 0xd2, 0x57, 0x33, - 0x58, 0x2b, 0xbd, 0xcc, 0xa5, 0xa2, 0x84, 0x32, 0x2c, 0x2f, 0xa9, 0x98, 0x40, 0x33, 0x90, 0x68, - 0xdc, 0x2c, 0x26, 0xd1, 0x3c, 0xe4, 0x7c, 0xa9, 0x57, 0xc5, 0x14, 0xca, 0xf2, 0x8c, 0x9c, 0x62, - 0xfa, 0xc6, 0xc7, 0x90, 0x11, 0xef, 0xbb, 0xa3, 0x47, 0x90, 0x66, 0x9b, 0x7b, 0x39, 0x7a, 0x9e, - 0xd3, 0x15, 0xb3, 0xb4, 0x32, 0x69, 0x21, 0x54, 0x4e, 0x10, 0xe4, 0x8d, 0x83, 0x6f, 0x03, 0x79, - 0xed, 0xfc, 0x97, 0x3f, 0x5f, 0x3e, 0xf1, 0xe5, 0xab, 0x65, 0xe9, 0xa7, 0xaf, 0x96, 0xa5, 0x9f, - 0xbd, 0x5a, 0x96, 0xfe, 0xe3, 0xd5, 0xb2, 0xf4, 0x27, 0xff, 0xb9, 0x7c, 0xe2, 0x93, 0x59, 0xae, - 0xf2, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x90, 0xac, 0x18, 0xaf, 0xd4, 0x4d, 0x00, 0x00, + // 4734 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7c, 0xcf, 0x6f, 0x1b, 0x49, + 0x76, 0xbf, 0x9b, 0x3f, 0x24, 0xf2, 0x91, 0x94, 0xa8, 0xb2, 0x3c, 0xa6, 0x35, 0x1e, 0x49, 0xe6, + 0xf8, 0xd7, 0xfc, 0xa2, 0x3c, 0xf6, 0xd7, 0xdf, 0x1d, 0xcf, 0xce, 0x60, 0xc7, 0xa2, 0x64, 0x89, + 0xb6, 0xc7, 0xd6, 0x34, 0xa9, 0xf1, 0xec, 0x4c, 0xb2, 0x9d, 0x56, 0x77, 0x89, 0xec, 0x88, 0xec, + 0x6e, 0x77, 0x37, 0x2d, 0x69, 0x82, 0x24, 0x40, 0x80, 0x20, 0xc1, 0x02, 0x09, 0x12, 0x20, 0x87, + 0x04, 0x39, 0xec, 0x00, 0x9b, 0xc3, 0x02, 0x01, 0xf2, 0x0f, 0x04, 0x41, 0x90, 0xdb, 0x04, 0xc9, + 0x61, 0x2f, 0x49, 0x16, 0x41, 0x60, 0x64, 0x9d, 0xcb, 0x22, 0xa7, 0x00, 0xc1, 0x5e, 0xe6, 0x14, + 0xd4, 0xaf, 0x66, 0x37, 0xd9, 0x4d, 0x52, 0x9a, 0x1e, 0x4c, 0x0e, 0x39, 0x91, 0xfd, 0xaa, 0xde, + 0xab, 0xaa, 0xf7, 0xaa, 0x5e, 0x7d, 0xaa, 0xde, 0xeb, 0x86, 0x15, 0xcd, 0xd2, 0x0e, 0x1c, 0x4b, + 0xd5, 0x3a, 0x6b, 0xf6, 0x41, 0x7b, 0x8d, 0xfe, 0xb3, 0xf7, 0xd6, 0x54, 0xdb, 0xa8, 0xd9, 0x8e, + 0xe5, 0x59, 0x68, 0xc1, 0xaf, 0x50, 0xe3, 0x85, 0x4b, 0xab, 0xd1, 0x3c, 0xba, 0xea, 0xa9, 0x8c, + 0x69, 0xa9, 0x1a, 0x5d, 0x03, 0x3b, 0x8e, 0xe5, 0xb8, 0xbc, 0xce, 0xe5, 0xe8, 0x3a, 0x3d, 0xec, + 0xa9, 0x01, 0x49, 0x37, 0xc2, 0xb5, 0x5c, 0xcf, 0x72, 0xd4, 0x36, 0x5e, 0xc3, 0x66, 0xdb, 0x30, + 0xc5, 0x0f, 0xe1, 0x7a, 0xa6, 0x69, 0x9c, 0xe3, 0x6a, 0x98, 0xa3, 0xef, 0x19, 0xdd, 0xb5, 0x4e, + 0x57, 0x5b, 0xf3, 0x8c, 0x1e, 0x76, 0x3d, 0xb5, 0x67, 0xf3, 0x7a, 0xb5, 0x88, 0x7a, 0x9e, 0xa3, + 0x6a, 0x86, 0xd9, 0x5e, 0x73, 0xb0, 0x66, 0x39, 0x3a, 0xd6, 0x15, 0xd7, 0x56, 0x4d, 0x5e, 0x7f, + 0xb1, 0x6d, 0xb5, 0x2d, 0xfa, 0x77, 0x8d, 0xfc, 0x63, 0xd4, 0xea, 0x6f, 0x43, 0x5e, 0x56, 0xcd, + 0x36, 0x6e, 0x98, 0xfb, 0x16, 0x7a, 0x0f, 0x32, 0x3a, 0x76, 0xb5, 0x8a, 0xb4, 0x2a, 0x5d, 0x2f, + 0xdc, 0xac, 0xd6, 0x46, 0x54, 0x57, 0xa3, 0x75, 0x37, 0xb0, 0xab, 0x39, 0x86, 0xed, 0x59, 0xce, + 0x7a, 0xe6, 0xcb, 0xe7, 0x2b, 0x67, 0x64, 0xca, 0x85, 0xfe, 0x1f, 0x64, 0xbb, 0x58, 0x75, 0x71, + 0x25, 0x45, 0xd9, 0x2b, 0x11, 0xec, 0x0f, 0x49, 0x39, 0x67, 0x62, 0x95, 0xab, 0x2f, 0x24, 0x98, + 0x93, 0xb1, 0x6b, 0x5b, 0xa6, 0x8b, 0xb7, 0xb1, 0xaa, 0x63, 0x07, 0xdd, 0x80, 0xb4, 0x77, 0x64, + 0x56, 0xd2, 0x54, 0xcc, 0x72, 0x84, 0x98, 0x96, 0xa3, 0x9a, 0xae, 0xaa, 0x79, 0x86, 0x65, 0xca, + 0xa4, 0x2a, 0x7a, 0x07, 0x0a, 0x0e, 0x76, 0xfb, 0x3d, 0x4c, 0x07, 0x5c, 0xc9, 0x50, 0xce, 0xf3, + 0x11, 0x9c, 0x4d, 0x5b, 0x35, 0x65, 0x60, 0x75, 0xc9, 0x7f, 0xb4, 0x02, 0x39, 0xb3, 0xdf, 0x53, + 0x0e, 0xf0, 0xb1, 0x5b, 0xc9, 0xae, 0x4a, 0xd7, 0xd3, 0xbc, 0x77, 0xb3, 0x66, 0xbf, 0xf7, 0x00, + 0x1f, 0xbb, 0xa8, 0x0e, 0x05, 0x87, 0x0c, 0x5a, 0x31, 0xcc, 0x7d, 0xcb, 0xad, 0xcc, 0xac, 0xa6, + 0xaf, 0x17, 0x6e, 0x5e, 0x8c, 0x53, 0x0d, 0x51, 0x23, 0x97, 0x00, 0x8e, 0x20, 0xb8, 0xd5, 0x0f, + 0x01, 0xb6, 0xb0, 0x27, 0xe3, 0xa7, 0x7d, 0xec, 0x7a, 0xe8, 0x0e, 0xcc, 0x74, 0xe8, 0x48, 0xb9, + 0xa2, 0xe3, 0x3a, 0xba, 0x9e, 0x23, 0x82, 0x7e, 0xfa, 0x7c, 0x45, 0x92, 0x39, 0xc3, 0xbb, 0x99, + 0x5f, 0x7c, 0xb1, 0x22, 0x55, 0x7f, 0x47, 0x82, 0x02, 0x95, 0xc7, 0xd4, 0x86, 0xea, 0x43, 0x02, + 0x2f, 0x45, 0x75, 0x2f, 0xa4, 0xe3, 0x51, 0xd1, 0xa8, 0x06, 0xd9, 0x67, 0x6a, 0xb7, 0x3f, 0xce, + 0x7c, 0x1f, 0x93, 0x72, 0x99, 0x55, 0xab, 0xfe, 0x8d, 0x04, 0xb0, 0xd3, 0x4f, 0x60, 0x50, 0x64, + 0xe2, 0x4c, 0xd5, 0xb2, 0x98, 0x38, 0xb4, 0x32, 0xba, 0x08, 0x33, 0x86, 0xd9, 0x35, 0x4c, 0x4c, + 0x27, 0x4a, 0x8e, 0x17, 0x72, 0x1a, 0x5a, 0x82, 0xec, 0x5e, 0xd7, 0x30, 0x75, 0x3a, 0x17, 0x44, + 0x21, 0x23, 0x71, 0x25, 0xca, 0x50, 0xa0, 0xdd, 0x4f, 0x50, 0x87, 0xd5, 0x9f, 0x4b, 0x70, 0xae, + 0x6e, 0x99, 0xba, 0x41, 0xa6, 0xa6, 0xda, 0xfd, 0x36, 0xd5, 0x73, 0x1b, 0xf2, 0xf8, 0xc8, 0x56, + 0x18, 0x67, 0x7a, 0x82, 0x49, 0x73, 0xf8, 0xc8, 0xa6, 0xff, 0xa6, 0xd0, 0xdb, 0xaf, 0xc2, 0x4b, + 0xc3, 0x43, 0x4c, 0x52, 0x85, 0xff, 0x24, 0xc1, 0x5c, 0xc3, 0x34, 0xbc, 0x6f, 0x53, 0x77, 0xbe, + 0x12, 0xd2, 0x23, 0x4a, 0x40, 0x37, 0xa0, 0xbc, 0xaf, 0x1a, 0xdd, 0xc7, 0x66, 0xcb, 0xea, 0xed, + 0xb9, 0x9e, 0x65, 0x62, 0x37, 0xa4, 0xab, 0x91, 0x52, 0xae, 0xb6, 0x8f, 0x61, 0xde, 0x1f, 0x56, + 0x92, 0xfa, 0x3a, 0x84, 0x72, 0xc3, 0xd4, 0x1c, 0xdc, 0xc3, 0x66, 0x12, 0x0a, 0xab, 0x42, 0xde, + 0x10, 0xe2, 0xa8, 0xd2, 0x84, 0x43, 0x1c, 0x90, 0xf9, 0x80, 0x7e, 0x03, 0x16, 0x02, 0x0d, 0x27, + 0xe9, 0x89, 0x2e, 0x41, 0xde, 0xc4, 0x87, 0xca, 0xc0, 0x70, 0xa2, 0x0f, 0x39, 0x13, 0x1f, 0x52, + 0x73, 0x55, 0x77, 0xa0, 0xb4, 0x81, 0xbb, 0xd8, 0xc3, 0x89, 0xf9, 0xd4, 0x5d, 0x98, 0x13, 0x12, + 0x93, 0x34, 0xcf, 0x17, 0x12, 0x20, 0x2e, 0x97, 0x6c, 0x07, 0x09, 0x58, 0xe8, 0x0a, 0xd9, 0xeb, + 0xbc, 0xbe, 0x63, 0xb2, 0x4d, 0x2b, 0x38, 0x45, 0x81, 0x15, 0xd0, 0x7d, 0x6b, 0xe0, 0x1e, 0x33, + 0xa3, 0xee, 0x91, 0x8d, 0xf9, 0x7e, 0x26, 0x97, 0x2a, 0xa7, 0xab, 0x87, 0x70, 0x36, 0xd4, 0xc3, + 0x24, 0x4d, 0xf9, 0x32, 0x64, 0x68, 0x2f, 0x53, 0xab, 0xe9, 0xeb, 0xc5, 0xf5, 0xd9, 0xaf, 0x9e, + 0xaf, 0xa4, 0x1f, 0xe0, 0x63, 0x99, 0x12, 0xab, 0x2d, 0x28, 0x34, 0x35, 0xd5, 0x4c, 0xca, 0x84, + 0x7c, 0x38, 0x3f, 0x94, 0xa0, 0xc8, 0xc4, 0x26, 0x39, 0x90, 0xdb, 0x90, 0x71, 0xac, 0x43, 0x36, + 0x90, 0xc2, 0xcd, 0x97, 0x23, 0x44, 0x3c, 0xc0, 0xc7, 0x41, 0x57, 0x42, 0xab, 0x57, 0x3f, 0x03, + 0x24, 0xe3, 0x67, 0xd8, 0x71, 0xf1, 0x37, 0x30, 0xd2, 0x3f, 0x96, 0xe0, 0x6c, 0x48, 0xfa, 0xff, + 0x82, 0x01, 0xff, 0x26, 0x9c, 0xaf, 0x77, 0xb0, 0x76, 0x50, 0xb7, 0x4c, 0xd7, 0x70, 0x3d, 0x6c, + 0x6a, 0xc7, 0x09, 0xcc, 0xf9, 0x4b, 0x90, 0x3f, 0x34, 0xbc, 0x8e, 0xa2, 0x1b, 0xfb, 0xfb, 0xd4, + 0x23, 0x88, 0xf9, 0x9c, 0x23, 0xe4, 0x0d, 0x63, 0x7f, 0x9f, 0xaf, 0x62, 0x05, 0x2a, 0xa3, 0xcd, + 0x27, 0xb9, 0x9e, 0x3f, 0x85, 0xf3, 0xeb, 0xb8, 0x6d, 0x98, 0x41, 0x08, 0x9a, 0x94, 0x0b, 0x52, + 0xa0, 0x32, 0x2a, 0x3b, 0xc9, 0xce, 0xff, 0x30, 0x0d, 0xe7, 0x36, 0x4d, 0x3d, 0xd1, 0xbe, 0x13, + 0x47, 0xa3, 0x59, 0xbd, 0x9e, 0xe1, 0x85, 0x0c, 0xc3, 0x69, 0xe8, 0x0e, 0xe4, 0x74, 0xac, 0xea, + 0x3e, 0x4e, 0x2b, 0xdc, 0x7c, 0x25, 0x20, 0x9a, 0x1c, 0x5a, 0x6a, 0x9d, 0xae, 0x56, 0x6b, 0x89, + 0xc3, 0x8d, 0xec, 0x57, 0x47, 0xbf, 0x06, 0xe7, 0x0d, 0xd3, 0xc3, 0x8e, 0xa9, 0x76, 0x15, 0x26, + 0x4d, 0xf1, 0x1c, 0xa3, 0xdd, 0xc6, 0x0e, 0x07, 0xf8, 0xd7, 0x23, 0x3a, 0xd9, 0xe0, 0x1c, 0x75, + 0xca, 0xd0, 0x62, 0xf5, 0xe5, 0x73, 0x46, 0x14, 0x19, 0x7d, 0x00, 0x45, 0x52, 0x60, 0x7a, 0xf4, + 0xd8, 0x40, 0x0e, 0x00, 0xe9, 0x71, 0x63, 0x67, 0x23, 0x2b, 0x30, 0x16, 0x42, 0x71, 0xd1, 0x2d, + 0xe2, 0x8c, 0x9f, 0xf6, 0x0d, 0x07, 0x2b, 0x6f, 0xdb, 0x5a, 0x65, 0x86, 0x6a, 0x00, 0x91, 0x7a, + 0x2f, 0x9e, 0xaf, 0x80, 0xcc, 0x8a, 0xde, 0xde, 0xa9, 0x13, 0xd7, 0xcc, 0xfe, 0xdb, 0x1a, 0xb7, + 0xf6, 0x9f, 0x49, 0xf0, 0xd2, 0xb0, 0x31, 0x92, 0xc5, 0xf3, 0x65, 0xcb, 0xc4, 0x8a, 0xdd, 0x51, + 0x5d, 0xcc, 0xf5, 0x17, 0xda, 0x0a, 0xe6, 0x2c, 0x13, 0xef, 0x90, 0x42, 0xa6, 0x13, 0xe6, 0x53, + 0xee, 0x67, 0x72, 0xe9, 0x72, 0xa6, 0xfa, 0x39, 0x2c, 0xdc, 0xd5, 0x7b, 0x86, 0xd9, 0xb4, 0xbb, + 0x46, 0x12, 0xa8, 0xe2, 0x32, 0xe4, 0x5d, 0x22, 0x8a, 0x6c, 0x59, 0x74, 0x9a, 0x04, 0xf6, 0x82, + 0x1c, 0x2d, 0x79, 0x80, 0x8f, 0xb9, 0x5e, 0xbe, 0x0f, 0x28, 0xd8, 0x76, 0x92, 0xf3, 0xbf, 0xc5, + 0x87, 0xf5, 0x21, 0x76, 0xda, 0xc9, 0x21, 0x07, 0xd1, 0x61, 0x2e, 0x35, 0xc9, 0x0e, 0xff, 0xae, + 0x04, 0x17, 0xa8, 0x6c, 0x3a, 0x4b, 0xf6, 0xb1, 0x43, 0x0f, 0xd0, 0x09, 0x18, 0xe4, 0x1a, 0xcc, + 0x78, 0xaa, 0xd3, 0xc6, 0x6c, 0xd1, 0x66, 0xd7, 0xe7, 0x49, 0x8d, 0xaf, 0x9e, 0xaf, 0xcc, 0x36, + 0x3d, 0xcb, 0xc1, 0x8d, 0x0d, 0x99, 0x17, 0xf3, 0x21, 0xaa, 0xb0, 0x14, 0xd5, 0x8d, 0x24, 0x87, + 0xfa, 0x5f, 0x12, 0x6f, 0xa3, 0xde, 0x61, 0x30, 0xc4, 0xee, 0x1a, 0x9a, 0xea, 0x26, 0x30, 0xd6, + 0x07, 0x50, 0xd0, 0xa8, 0x4c, 0xc5, 0x3b, 0xb6, 0x19, 0xa0, 0x9c, 0xbb, 0x79, 0x39, 0xb2, 0x8f, + 0xb4, 0x4d, 0xd6, 0x81, 0xd6, 0xb1, 0x2d, 0x76, 0x36, 0xd0, 0x7c, 0x0a, 0xda, 0x80, 0x59, 0xa6, + 0x19, 0x82, 0xbc, 0x88, 0xb7, 0x18, 0x23, 0x88, 0xac, 0xe9, 0x16, 0xad, 0x2c, 0x2e, 0x15, 0x38, + 0x2b, 0xd7, 0xea, 0x1e, 0xbc, 0x1c, 0x39, 0xe2, 0xa4, 0xf1, 0x27, 0xc5, 0x75, 0x0f, 0x2d, 0xeb, + 0xa0, 0x6f, 0x27, 0xa0, 0xce, 0x57, 0x01, 0x7a, 0xea, 0x91, 0x42, 0x6f, 0x37, 0x5c, 0x3e, 0x7d, + 0xf8, 0x11, 0xa1, 0xa7, 0x1e, 0xd1, 0xb6, 0x5c, 0xb4, 0x0c, 0xb3, 0x0e, 0x43, 0x26, 0x21, 0x9f, + 0x23, 0x88, 0x3e, 0x8c, 0x21, 0xce, 0xe6, 0xbf, 0x09, 0x8c, 0x09, 0x76, 0x31, 0x49, 0x2f, 0xf8, + 0x01, 0xcc, 0xf8, 0x3d, 0x4d, 0x9f, 0xe8, 0x52, 0x8b, 0xf3, 0xa1, 0x5d, 0x58, 0xb0, 0x1d, 0xbc, + 0x8f, 0x3d, 0xad, 0x83, 0x75, 0x31, 0xec, 0xf4, 0x09, 0x85, 0x95, 0x07, 0x22, 0x98, 0x86, 0xaa, + 0x7f, 0x20, 0xc1, 0xd9, 0x6d, 0xac, 0x3a, 0xde, 0x1e, 0x56, 0xbd, 0xd6, 0x51, 0x12, 0x3b, 0xf1, + 0x6d, 0x48, 0x9b, 0xd6, 0x21, 0x3f, 0xea, 0x8e, 0xdf, 0x66, 0x79, 0xb7, 0x48, 0x7d, 0x3e, 0x19, + 0x3f, 0x83, 0xc5, 0x70, 0x77, 0x92, 0x9c, 0x85, 0x3f, 0x49, 0x43, 0x7e, 0xab, 0x9e, 0xc0, 0x10, + 0xdf, 0xe3, 0xe7, 0x89, 0x78, 0xfd, 0xfb, 0xcd, 0xd4, 0xb6, 0xea, 0x0f, 0xf0, 0xb1, 0x00, 0xa7, + 0x84, 0x0b, 0xdd, 0x85, 0xbc, 0xd7, 0x71, 0xb0, 0xdb, 0xb1, 0xba, 0x3a, 0xc7, 0x10, 0x53, 0xa9, + 0x69, 0xc0, 0x85, 0xba, 0x70, 0xce, 0x3b, 0x32, 0x29, 0x5e, 0x50, 0xda, 0x9a, 0x32, 0x10, 0x97, + 0x9d, 0x46, 0xdc, 0x12, 0x47, 0x06, 0xa8, 0x75, 0x64, 0x92, 0x11, 0x6e, 0xd5, 0x5b, 0x42, 0x80, + 0x8c, 0x3c, 0x4e, 0xd3, 0x7c, 0xda, 0xd2, 0x01, 0x64, 0xe9, 0x28, 0xd0, 0x05, 0x48, 0x93, 0xad, + 0x53, 0x0a, 0x6f, 0x9d, 0x84, 0x46, 0x07, 0x25, 0x1a, 0x38, 0x89, 0xed, 0x07, 0x5c, 0x6c, 0x06, + 0xf0, 0x79, 0xf0, 0x11, 0x00, 0x51, 0x61, 0x92, 0xd6, 0xff, 0xbb, 0x34, 0xcc, 0xed, 0xf4, 0xdd, + 0x4e, 0x32, 0xb3, 0xbc, 0x0e, 0x60, 0xf7, 0xdd, 0x0e, 0x76, 0x14, 0xef, 0xc8, 0xe4, 0x03, 0x9e, + 0x70, 0x49, 0x2c, 0x46, 0xcc, 0xf8, 0x5a, 0x47, 0x26, 0x7a, 0xcc, 0x85, 0x60, 0x65, 0x70, 0xd3, + 0xfc, 0x7a, 0x40, 0x08, 0xbf, 0xa7, 0xaf, 0xb1, 0x0b, 0xfa, 0x9a, 0xb8, 0xa7, 0xaf, 0xb5, 0x8e, + 0xcc, 0x0f, 0xb1, 0xa7, 0x86, 0x04, 0x62, 0x22, 0xf0, 0x3d, 0x98, 0x25, 0x0f, 0x8a, 0x67, 0x9d, + 0x64, 0x62, 0xcd, 0x10, 0x9e, 0x96, 0x25, 0x56, 0x6e, 0xf6, 0x64, 0x2b, 0x97, 0x98, 0x9e, 0x35, + 0x4a, 0xf6, 0xb5, 0x19, 0xba, 0xaf, 0x45, 0x69, 0x82, 0xeb, 0x3e, 0xb0, 0xa3, 0xe5, 0x68, 0xbb, + 0x64, 0x3f, 0x5b, 0x82, 0xec, 0xbe, 0xe5, 0x68, 0xb8, 0x32, 0x1b, 0xbc, 0xea, 0xa2, 0x24, 0xdf, + 0x49, 0xe7, 0xca, 0xf9, 0xea, 0x9f, 0x4b, 0x30, 0xef, 0xdb, 0x30, 0x49, 0x07, 0x5d, 0x0f, 0x59, + 0xe2, 0xe4, 0xe6, 0x24, 0xda, 0xaf, 0xfe, 0x65, 0x0a, 0xe6, 0x3f, 0xea, 0x63, 0xe7, 0x38, 0x99, + 0x29, 0xb6, 0xce, 0x02, 0x10, 0xa9, 0x53, 0x4e, 0x0b, 0x1a, 0x92, 0x78, 0x13, 0xe6, 0x0f, 0x55, + 0xc3, 0x53, 0xf6, 0x2d, 0x47, 0xe9, 0xdb, 0xba, 0xea, 0x85, 0xef, 0xa9, 0x4b, 0xa4, 0xf0, 0x9e, + 0xe5, 0xec, 0xd2, 0x22, 0x84, 0x01, 0x1d, 0x98, 0xd6, 0xa1, 0xa9, 0x10, 0xb2, 0x61, 0xb6, 0x89, + 0x32, 0xdc, 0x4a, 0x86, 0xde, 0x9a, 0x7c, 0xe7, 0x5f, 0x9f, 0xaf, 0xdc, 0x6a, 0x1b, 0x5e, 0xa7, + 0xbf, 0x57, 0xd3, 0xac, 0xde, 0x9a, 0xdf, 0x1d, 0x7d, 0x6f, 0x2d, 0x22, 0x06, 0xd4, 0xef, 0x1b, + 0x7a, 0x6d, 0x77, 0xb7, 0xb1, 0x21, 0x97, 0xa9, 0xc8, 0x27, 0x4c, 0x62, 0xeb, 0xc8, 0x14, 0xb8, + 0xe3, 0x2b, 0x09, 0xca, 0x03, 0x6d, 0x25, 0x69, 0xcc, 0x4d, 0x28, 0x3c, 0xed, 0x63, 0xc7, 0xc0, + 0xfa, 0x89, 0xad, 0x09, 0x9c, 0x91, 0x2c, 0xa6, 0x4f, 0xa1, 0x18, 0xd2, 0x43, 0xfa, 0xeb, 0xe9, + 0xa1, 0x70, 0x38, 0x50, 0x41, 0xf5, 0xdf, 0x52, 0xb0, 0x28, 0x63, 0xd7, 0xea, 0x3e, 0xc3, 0x0d, + 0x7a, 0x90, 0x4b, 0x60, 0xbe, 0x3c, 0x06, 0xe0, 0xe7, 0xc8, 0xaf, 0x33, 0x6d, 0xf2, 0x4c, 0x06, + 0x51, 0xc0, 0x3a, 0xcc, 0xb8, 0x9e, 0xea, 0xf5, 0xd9, 0xf5, 0x5e, 0x34, 0x5a, 0x0d, 0xa8, 0xb0, + 0x49, 0xeb, 0x0a, 0x9f, 0xc2, 0x38, 0xd1, 0xdb, 0xb0, 0xa0, 0x63, 0xdb, 0xc1, 0x9a, 0xea, 0x61, + 0x5d, 0xb1, 0x2d, 0xc3, 0xb5, 0xcc, 0xf0, 0x4d, 0xf5, 0xa0, 0x78, 0x87, 0x96, 0xa2, 0xef, 0xc2, + 0x0c, 0xaf, 0x97, 0xa5, 0xcd, 0xbe, 0x12, 0xe5, 0x4c, 0x68, 0x85, 0x80, 0x2f, 0xe1, 0x2c, 0x7c, + 0x6e, 0xfd, 0x0a, 0x9c, 0x1b, 0xd2, 0x6e, 0xa2, 0xf1, 0x95, 0x14, 0x5c, 0x08, 0x8b, 0x4f, 0xe8, + 0x52, 0xf5, 0xff, 0x2c, 0xe8, 0x5b, 0x70, 0x0e, 0x8a, 0x8f, 0x2c, 0xcb, 0x87, 0xe1, 0xd5, 0x12, + 0x14, 0xd8, 0x33, 0x55, 0x32, 0x39, 0x0a, 0x46, 0x59, 0x20, 0xe1, 0x53, 0x6f, 0x31, 0xa1, 0x23, + 0xfa, 0xe9, 0x02, 0x40, 0x5c, 0x13, 0x2d, 0x28, 0x7d, 0x03, 0x67, 0xfa, 0x9f, 0x48, 0x80, 0x5a, + 0x4e, 0xdf, 0x24, 0x66, 0x7b, 0x68, 0xb5, 0x13, 0x18, 0xe3, 0x12, 0x64, 0x0d, 0x53, 0xc7, 0x47, + 0x74, 0x8c, 0x19, 0x31, 0x12, 0x4a, 0x42, 0xb7, 0x21, 0xc7, 0xc3, 0xd7, 0x2c, 0x9a, 0x95, 0xf6, + 0x31, 0xe8, 0x2c, 0x0b, 0x58, 0x6f, 0x7c, 0x35, 0xf8, 0x2b, 0xcf, 0xb2, 0x98, 0xb5, 0x08, 0xf5, + 0x7d, 0x0a, 0x67, 0x43, 0x3d, 0x4d, 0x52, 0x0d, 0xff, 0x40, 0x2f, 0xaf, 0xe9, 0xd8, 0x93, 0xba, + 0xd4, 0x38, 0x55, 0x02, 0x02, 0x7a, 0x1f, 0xc0, 0x76, 0xf0, 0x33, 0x85, 0xb1, 0xa6, 0xa7, 0x62, + 0xcd, 0x13, 0x0e, 0x4a, 0xe0, 0x9a, 0xfa, 0x47, 0x09, 0x16, 0x93, 0xbe, 0xa3, 0xf9, 0x16, 0x87, + 0xd3, 0x84, 0x32, 0x7d, 0x6c, 0x98, 0xfb, 0x56, 0x62, 0xf7, 0x64, 0x7f, 0x28, 0xc1, 0x42, 0x40, + 0x6a, 0x92, 0xb8, 0xe3, 0x74, 0xa9, 0x27, 0x9f, 0x11, 0x24, 0x10, 0x9c, 0x81, 0x49, 0xce, 0xef, + 0xdf, 0x4b, 0xc1, 0x4b, 0x75, 0xab, 0x67, 0xf7, 0x3d, 0x4c, 0x23, 0x12, 0x6e, 0xbf, 0x97, 0xc0, + 0x9c, 0x58, 0x86, 0xd9, 0x67, 0xd8, 0x71, 0x0d, 0x8b, 0x6d, 0x52, 0x25, 0x71, 0xaf, 0xc2, 0x89, + 0xe8, 0xd7, 0xa1, 0xa0, 0xf1, 0xd6, 0xc4, 0x8a, 0x2f, 0xae, 0x37, 0x48, 0x9d, 0x53, 0x82, 0xa7, + 0x17, 0xcf, 0x57, 0x40, 0xf4, 0xbf, 0xb1, 0x21, 0x83, 0x90, 0xde, 0xd0, 0xd1, 0x2a, 0xe4, 0x5c, + 0x53, 0xb5, 0xdd, 0x8e, 0x15, 0xbe, 0x58, 0xf6, 0xa9, 0xdc, 0xee, 0x3f, 0x80, 0xf3, 0x23, 0x8a, + 0x48, 0x52, 0xd3, 0x7b, 0xb0, 0xb2, 0xe1, 0xef, 0x83, 0x1f, 0x63, 0xc7, 0xd8, 0x3f, 0x4e, 0x4e, + 0xe3, 0x7c, 0x0c, 0x6d, 0x58, 0x8d, 0x6f, 0x23, 0xc9, 0xc1, 0xfc, 0x6c, 0x16, 0x4a, 0x9b, 0x47, + 0xb6, 0xe5, 0x78, 0x4d, 0x06, 0x39, 0xd0, 0x7d, 0xc8, 0xd9, 0x8e, 0xf5, 0xcc, 0x10, 0x82, 0xe7, + 0x22, 0xe3, 0x1e, 0x21, 0x9e, 0x1d, 0x5e, 0xdf, 0x3f, 0xed, 0xf1, 0x67, 0x24, 0x43, 0xfe, 0xa1, + 0xa5, 0xa9, 0xdd, 0x7b, 0x46, 0x57, 0xac, 0x95, 0xda, 0x24, 0x61, 0x35, 0x9f, 0x63, 0x47, 0xf5, + 0x3a, 0xc2, 0x63, 0xf8, 0x44, 0xb4, 0x05, 0xb9, 0x6d, 0xcf, 0xb3, 0x49, 0x21, 0x77, 0x37, 0x57, + 0x26, 0x8a, 0x24, 0x0c, 0xa2, 0x73, 0x82, 0x19, 0xc9, 0xb0, 0xb0, 0x65, 0x59, 0xed, 0x2e, 0xae, + 0x77, 0xad, 0xbe, 0x5e, 0xb7, 0xcc, 0x7d, 0xa3, 0xcd, 0x0f, 0xd3, 0x97, 0x27, 0x4a, 0xdc, 0xaa, + 0x37, 0xe5, 0x51, 0x76, 0xf4, 0x3d, 0xc8, 0x35, 0x6f, 0x71, 0x51, 0xec, 0x74, 0xfd, 0xea, 0x44, + 0x51, 0xcd, 0x5b, 0xb2, 0xcf, 0x84, 0xb6, 0xa1, 0x70, 0xf7, 0xf3, 0xbe, 0x83, 0xb9, 0x8c, 0x19, + 0x2a, 0xe3, 0xea, 0x44, 0x19, 0x94, 0x47, 0x0e, 0xb2, 0x2e, 0xad, 0x41, 0x29, 0xa4, 0x49, 0x54, + 0x81, 0x8c, 0x4d, 0x94, 0x46, 0x8c, 0x9a, 0x17, 0xf7, 0x54, 0x84, 0xc2, 0xe6, 0xdc, 0xd2, 0x9b, + 0x90, 0x21, 0xba, 0x21, 0x6b, 0x7e, 0x4f, 0x75, 0xf1, 0xae, 0x63, 0x84, 0xaa, 0x0a, 0x22, 0xaf, + 0xfd, 0x57, 0x12, 0xa4, 0x9a, 0xb7, 0xd0, 0x45, 0x98, 0xd9, 0xeb, 0x6b, 0x07, 0xd8, 0x0b, 0xd5, + 0xe5, 0x34, 0x52, 0x6a, 0x3b, 0x78, 0xdf, 0x60, 0x50, 0xc1, 0x2f, 0x65, 0x34, 0xf4, 0x2a, 0x80, + 0xaa, 0x69, 0xd8, 0x75, 0x69, 0x98, 0x26, 0x1d, 0xa8, 0x91, 0x67, 0xf4, 0x07, 0xf8, 0x98, 0x88, + 0x70, 0xb1, 0xe6, 0x60, 0xb6, 0xe6, 0x7d, 0x11, 0x8c, 0x46, 0x44, 0x78, 0xb8, 0x67, 0x2b, 0x9e, + 0x75, 0x80, 0x19, 0x06, 0xf5, 0x45, 0x10, 0x7a, 0x8b, 0x90, 0x79, 0x87, 0xb7, 0x20, 0xbd, 0x55, + 0x6f, 0x7e, 0x9d, 0x0e, 0x73, 0x41, 0x3f, 0x92, 0x20, 0x4b, 0x15, 0x8d, 0xaa, 0x90, 0xd7, 0x2c, + 0xd3, 0x53, 0x0d, 0x93, 0xaf, 0x15, 0xbf, 0x71, 0x9f, 0x3c, 0x41, 0x05, 0xd7, 0xa0, 0xa8, 0x6a, + 0x9a, 0xd5, 0x37, 0x3d, 0xc5, 0x54, 0x7b, 0x38, 0xa4, 0x84, 0x02, 0x2f, 0x79, 0xa4, 0xf6, 0x30, + 0xba, 0x02, 0xe2, 0x91, 0x2a, 0x2b, 0xa8, 0x0b, 0xe0, 0x05, 0x7e, 0x48, 0x8b, 0xfb, 0x90, 0xbf, + 0x90, 0x60, 0xe1, 0x89, 0x63, 0x78, 0x78, 0x5d, 0xf5, 0xb4, 0x4e, 0x02, 0x9b, 0xc1, 0xbb, 0x90, + 0xd7, 0x55, 0x4f, 0x65, 0x39, 0x8f, 0xa9, 0xf1, 0xdc, 0x7c, 0xb1, 0x91, 0xfa, 0x34, 0xef, 0x11, + 0x41, 0x86, 0xfc, 0x67, 0x3b, 0x84, 0x4c, 0xff, 0x0f, 0xc2, 0x59, 0xc1, 0x5e, 0x26, 0xe9, 0xdc, + 0xfe, 0x59, 0x12, 0xce, 0x2d, 0x81, 0xd1, 0x7f, 0x00, 0xb3, 0xfc, 0x54, 0xc6, 0xc7, 0xbe, 0x3a, + 0x69, 0x55, 0x8a, 0x85, 0xc3, 0xd9, 0xd0, 0x3a, 0x80, 0xeb, 0xa9, 0x8e, 0xa7, 0x78, 0x46, 0x6f, + 0xba, 0xe8, 0xb4, 0x98, 0x4e, 0x94, 0x8d, 0x50, 0x07, 0xa6, 0x2d, 0xad, 0xf7, 0xbb, 0x07, 0x8f, + 0xed, 0x66, 0xbf, 0xd7, 0x53, 0x9d, 0x63, 0x74, 0x49, 0xd8, 0xc6, 0xf8, 0x1c, 0xd3, 0xb1, 0xa5, + 0x43, 0x26, 0x30, 0x3e, 0xc7, 0x64, 0xfd, 0xf3, 0x0c, 0x8b, 0x41, 0x29, 0xa5, 0xa0, 0xd7, 0xa0, + 0x44, 0xd1, 0xbb, 0x82, 0x4d, 0xcf, 0x31, 0xb0, 0xcb, 0x91, 0x3b, 0xab, 0x52, 0xa4, 0x45, 0x9b, + 0xac, 0x04, 0xbd, 0x01, 0x73, 0xee, 0xb1, 0xeb, 0xe1, 0x9e, 0xc2, 0x72, 0x7e, 0x59, 0x32, 0x9a, + 0xa8, 0x5b, 0x62, 0x65, 0x32, 0x2b, 0xaa, 0xfe, 0x4b, 0x0a, 0xe6, 0x84, 0xfe, 0x93, 0x84, 0x5f, + 0xeb, 0x90, 0xdd, 0x37, 0xba, 0x7e, 0x8c, 0x25, 0xde, 0x3d, 0x0a, 0x49, 0x35, 0xe2, 0x04, 0xfd, + 0xcb, 0x46, 0xc2, 0xba, 0xf4, 0xd7, 0x12, 0x64, 0xe8, 0x7e, 0xf2, 0x36, 0x64, 0xe8, 0x84, 0x96, + 0xa6, 0x99, 0xd0, 0xb4, 0xaa, 0xef, 0x49, 0x53, 0xc3, 0x9e, 0x14, 0xbd, 0x04, 0x33, 0x6e, 0x47, + 0xbd, 0xfd, 0xf6, 0x4d, 0xea, 0x8b, 0x8a, 0x32, 0x7f, 0x42, 0xeb, 0x90, 0xc3, 0xb4, 0x47, 0x58, + 0xe7, 0x3e, 0x3d, 0x6a, 0xf6, 0x84, 0x4c, 0x2a, 0xec, 0x27, 0xf8, 0x58, 0xf4, 0xea, 0x7e, 0x26, + 0x97, 0x29, 0x67, 0xab, 0xbf, 0x4c, 0x43, 0xa9, 0xd1, 0x4b, 0x68, 0x66, 0xdf, 0x0d, 0xab, 0x33, + 0x6a, 0x3b, 0x0d, 0xb5, 0x35, 0xaa, 0xcd, 0xb0, 0x6b, 0x48, 0x9f, 0xcc, 0x35, 0x34, 0x60, 0xc6, + 0xc1, 0x3c, 0x21, 0x9a, 0xb4, 0xff, 0xc6, 0xc4, 0xf6, 0x5b, 0xea, 0x5e, 0x17, 0xcb, 0x84, 0xc7, + 0x8f, 0x9d, 0x51, 0x01, 0x4b, 0xbf, 0xc5, 0x6d, 0xfa, 0x0e, 0xa4, 0x75, 0x43, 0x68, 0x62, 0xda, + 0x75, 0x4a, 0x58, 0xa6, 0x32, 0x6d, 0x26, 0x68, 0xda, 0x60, 0x68, 0x71, 0xa9, 0x09, 0x30, 0xe8, + 0x1b, 0xba, 0x0c, 0x33, 0x56, 0x57, 0x27, 0xb8, 0x58, 0xa2, 0xd8, 0xb9, 0xc4, 0x4f, 0xc2, 0xd9, + 0xc7, 0x5d, 0xbd, 0xb1, 0x21, 0x67, 0xad, 0xae, 0xde, 0xd0, 0xd1, 0x05, 0xc8, 0x99, 0xf8, 0x50, + 0xa1, 0x89, 0xf0, 0x34, 0x55, 0x41, 0x9e, 0x35, 0xf1, 0xe1, 0x06, 0x76, 0xb5, 0xa0, 0x37, 0xe7, + 0x76, 0xff, 0x91, 0x04, 0x73, 0x42, 0x17, 0xc9, 0xae, 0xa8, 0x9c, 0xd1, 0xe3, 0xf3, 0x33, 0x7d, + 0xb2, 0xf9, 0x29, 0xf8, 0x78, 0x92, 0xd8, 0xc7, 0x70, 0x96, 0xa5, 0x53, 0x68, 0xaa, 0xe7, 0x61, + 0x27, 0x31, 0x44, 0xfc, 0x9f, 0x12, 0x2c, 0x86, 0x05, 0x27, 0x39, 0xfe, 0x07, 0x43, 0x61, 0xdb, + 0xb7, 0x22, 0x84, 0x44, 0xb5, 0xce, 0xc2, 0xaf, 0xe1, 0x08, 0xee, 0xd2, 0x07, 0x90, 0xa5, 0xe4, + 0x53, 0xb8, 0x16, 0xae, 0xc4, 0x0e, 0x2c, 0xdc, 0xd5, 0xf5, 0x66, 0x93, 0x4f, 0xa6, 0xaf, 0xbd, + 0xc2, 0xc5, 0xee, 0x9b, 0x8a, 0xda, 0x7d, 0x83, 0x2d, 0x25, 0xb9, 0xfb, 0xfe, 0xfd, 0x22, 0x14, + 0x79, 0xdf, 0x77, 0x4d, 0x72, 0x58, 0x5c, 0x83, 0x74, 0x9b, 0xe3, 0xae, 0x42, 0xe4, 0x4d, 0xe1, + 0xe0, 0x9d, 0x05, 0x99, 0xd4, 0x24, 0x0c, 0x76, 0xdf, 0x8b, 0x08, 0x32, 0x0e, 0x22, 0x4d, 0x03, + 0x06, 0xbb, 0xef, 0xa1, 0x8f, 0x60, 0x5e, 0x1b, 0xe4, 0x8a, 0x2b, 0x84, 0x39, 0x1d, 0x9b, 0xba, + 0x15, 0x99, 0x38, 0x2f, 0xcf, 0x69, 0x21, 0x32, 0xba, 0x1b, 0x4c, 0x50, 0xce, 0xc4, 0x42, 0xfa, + 0xe1, 0x9c, 0xe8, 0x40, 0xfe, 0x32, 0x7a, 0x07, 0x66, 0x74, 0x9a, 0xf0, 0xca, 0x8f, 0x04, 0x51, + 0x4b, 0x2b, 0x94, 0x5d, 0x2c, 0xf3, 0xfa, 0x68, 0x1b, 0x8a, 0xec, 0x1f, 0xcb, 0x03, 0xe0, 0x5b, + 0xc7, 0x95, 0x78, 0xfe, 0xc0, 0xf5, 0xb4, 0x5c, 0xd0, 0x07, 0x34, 0x74, 0x13, 0x32, 0xae, 0xa6, + 0x9a, 0x34, 0xec, 0x16, 0x1d, 0x22, 0x09, 0x24, 0x8c, 0xca, 0xb4, 0x2e, 0x7a, 0x02, 0x0b, 0x7b, + 0xb8, 0x6d, 0x98, 0x8a, 0x37, 0xb8, 0x38, 0xae, 0xe4, 0x46, 0xee, 0xaa, 0x7d, 0xef, 0x10, 0x9d, + 0xa7, 0x28, 0x97, 0xf7, 0x86, 0x0a, 0x88, 0x99, 0xb0, 0xa9, 0x87, 0xc4, 0xe6, 0x63, 0xcd, 0x14, + 0x99, 0x40, 0x28, 0xcf, 0xe1, 0x10, 0x19, 0x6d, 0x42, 0x41, 0x25, 0xeb, 0x53, 0xa1, 0xd9, 0x5d, + 0x15, 0x88, 0x3d, 0xc6, 0x8d, 0xe4, 0x99, 0xc9, 0xa0, 0xfa, 0xa4, 0x81, 0x98, 0x1e, 0x76, 0xda, + 0xb8, 0x52, 0x18, 0x2f, 0x26, 0x78, 0x69, 0xcc, 0xc5, 0x50, 0x12, 0x7a, 0x00, 0xa5, 0x8e, 0x48, + 0x6e, 0xa0, 0x37, 0xfc, 0xc5, 0xd8, 0x73, 0x5c, 0x44, 0x4e, 0x86, 0x5c, 0xec, 0x04, 0x88, 0xe8, + 0x4d, 0x48, 0xb5, 0xb5, 0x4a, 0x89, 0x4a, 0xb8, 0x38, 0x2e, 0x03, 0x41, 0x4e, 0xb5, 0x35, 0xf4, + 0x1e, 0xe4, 0x58, 0x8c, 0xf6, 0xc8, 0xac, 0xcc, 0xc5, 0x2e, 0xde, 0x70, 0x78, 0x5c, 0xa6, 0xb1, + 0x64, 0xd2, 0xd6, 0x36, 0x14, 0xd9, 0xf5, 0x6d, 0x97, 0xe6, 0xc6, 0x54, 0xe6, 0x63, 0x27, 0xdc, + 0x68, 0x92, 0x8f, 0xcc, 0x5e, 0x5c, 0x62, 0x34, 0xf4, 0x08, 0xe6, 0x1c, 0x76, 0x6f, 0xaf, 0xb0, + 0x28, 0x45, 0xa5, 0x4c, 0x65, 0x5d, 0x8b, 0x76, 0x25, 0x23, 0xf1, 0x31, 0xb9, 0xe4, 0x04, 0xa9, + 0xe8, 0x07, 0xb0, 0x18, 0x96, 0xc7, 0x97, 0xc4, 0x02, 0x95, 0xfa, 0xe6, 0x44, 0xa9, 0xc1, 0x95, + 0x81, 0x9c, 0x91, 0x22, 0x74, 0x1b, 0xb2, 0xcc, 0xe6, 0x88, 0x0a, 0x5c, 0x89, 0x10, 0x18, 0x32, + 0x37, 0xab, 0x4d, 0x14, 0xe6, 0xf1, 0x2b, 0x6b, 0xa5, 0x6b, 0xb5, 0x2b, 0x67, 0x63, 0x15, 0x36, + 0x7a, 0x07, 0x2f, 0x17, 0xbc, 0x01, 0x8d, 0xcc, 0x19, 0x87, 0xd1, 0xf9, 0x5d, 0xea, 0x62, 0xec, + 0x9c, 0x89, 0xb8, 0xc7, 0x96, 0x8b, 0x4e, 0x80, 0x48, 0xed, 0xc8, 0x52, 0x9f, 0x14, 0xba, 0xec, + 0xcf, 0xc5, 0xdb, 0x71, 0x24, 0x5d, 0x5c, 0x2e, 0x38, 0x03, 0x1a, 0x6a, 0x41, 0x59, 0x63, 0xb7, + 0x69, 0x8a, 0xb8, 0x8b, 0xab, 0xbc, 0x44, 0xa5, 0xbd, 0x16, 0xe9, 0x53, 0xa3, 0x6e, 0x20, 0xe5, + 0x79, 0x2d, 0x4c, 0x47, 0x36, 0x2c, 0x05, 0x42, 0x4d, 0xcf, 0xe8, 0x05, 0xd7, 0x40, 0xfe, 0x79, + 0x2a, 0xff, 0x66, 0xa4, 0x9b, 0x1b, 0x7b, 0xf1, 0x26, 0x57, 0xf4, 0x98, 0x0a, 0xc4, 0x99, 0x51, + 0xf9, 0x8a, 0x36, 0x48, 0xd5, 0xae, 0x54, 0x62, 0x9d, 0x59, 0x4c, 0x52, 0xb9, 0x5c, 0xd6, 0x86, + 0x0a, 0x88, 0x67, 0x35, 0x2d, 0xcb, 0xae, 0x5c, 0x88, 0xf5, 0xac, 0x81, 0x70, 0x96, 0x4c, 0xeb, + 0x92, 0x45, 0x6a, 0x98, 0x86, 0x47, 0x37, 0xa8, 0xa5, 0xd8, 0x45, 0x1a, 0x7e, 0x2d, 0x49, 0x9e, + 0x35, 0xd8, 0x33, 0x59, 0x5a, 0x1e, 0xbf, 0xfb, 0xe7, 0x53, 0xe5, 0x62, 0xec, 0xd2, 0x8a, 0x0a, + 0x12, 0xc8, 0x25, 0x2f, 0x48, 0x25, 0x4b, 0x8b, 0x39, 0xbd, 0x21, 0xa9, 0xaf, 0xc4, 0x2e, 0xad, + 0xd8, 0x1c, 0x51, 0x19, 0xa9, 0x23, 0x45, 0xe4, 0xdc, 0x4b, 0x05, 0xd2, 0x57, 0x1a, 0x2b, 0xcb, + 0xb1, 0x7b, 0xe8, 0x70, 0x08, 0x40, 0xce, 0x77, 0x05, 0x85, 0x38, 0xe6, 0x43, 0xc7, 0xf0, 0xb0, + 0xb2, 0xa7, 0x7a, 0x5a, 0xa7, 0xb2, 0x12, 0xeb, 0x98, 0x47, 0x6e, 0x3c, 0x64, 0x38, 0xf4, 0x49, + 0x64, 0x2b, 0x66, 0xe7, 0xa9, 0xca, 0xea, 0x84, 0xb3, 0x81, 0xbf, 0x15, 0xb3, 0xfa, 0xe8, 0x7b, + 0x90, 0x7f, 0xda, 0xc7, 0xce, 0x31, 0x75, 0xac, 0x97, 0x62, 0x5f, 0x58, 0x1d, 0xca, 0x0a, 0x91, + 0x73, 0x4f, 0x39, 0x81, 0x34, 0xcd, 0xa0, 0x72, 0xa5, 0x1a, 0xdb, 0x74, 0xe8, 0x98, 0x23, 0xf3, + 0xfa, 0x48, 0x85, 0x73, 0xcc, 0x3e, 0x3c, 0xad, 0xd4, 0xe1, 0x99, 0x9b, 0x95, 0x57, 0xa9, 0xa0, + 0x58, 0xac, 0x1a, 0x99, 0xd9, 0x2a, 0x9f, 0x55, 0x47, 0xcb, 0x88, 0xf3, 0xe1, 0xdb, 0x27, 0xc3, + 0xb7, 0x95, 0xcb, 0xb1, 0xce, 0x27, 0x02, 0xdd, 0xcb, 0x45, 0x35, 0x40, 0x64, 0x9b, 0xa8, 0xae, + 0xb8, 0xae, 0x47, 0x40, 0x65, 0xe5, 0xca, 0x98, 0x4d, 0x74, 0x08, 0xe3, 0x92, 0x4d, 0x54, 0x6f, + 0x32, 0xbe, 0x77, 0x33, 0x5f, 0xb2, 0x73, 0xcf, 0xcb, 0xe5, 0x8b, 0xd5, 0x1f, 0x2f, 0x42, 0x49, + 0x00, 0x4e, 0x06, 0x26, 0x6f, 0x04, 0xc1, 0xe4, 0x72, 0x1c, 0x98, 0x64, 0x1c, 0x0c, 0x4d, 0xde, + 0x08, 0xa2, 0xc9, 0xe5, 0x38, 0x34, 0x29, 0x38, 0x08, 0x9c, 0x94, 0xe3, 0xe0, 0xe4, 0x6b, 0x53, + 0xc0, 0x49, 0x2e, 0x68, 0x18, 0x4f, 0xae, 0x8f, 0xe2, 0xc9, 0xcb, 0xe3, 0xf1, 0x24, 0x17, 0x14, + 0x00, 0x94, 0x77, 0x86, 0x00, 0xe5, 0xa5, 0x31, 0x80, 0x92, 0x73, 0x0b, 0x44, 0xd9, 0x88, 0x44, + 0x94, 0x57, 0x27, 0x21, 0x4a, 0x2e, 0x25, 0x04, 0x29, 0x6f, 0x85, 0x20, 0xe5, 0x4a, 0x2c, 0xa4, + 0xe4, 0xbc, 0x0c, 0x53, 0x7e, 0x12, 0x8f, 0x29, 0xdf, 0x98, 0x0a, 0x53, 0x72, 0x69, 0xa3, 0xa0, + 0x52, 0x8e, 0x03, 0x95, 0xaf, 0x4d, 0x01, 0x2a, 0x85, 0xb1, 0x86, 0x50, 0xe5, 0xbd, 0x28, 0x54, + 0x79, 0x65, 0x02, 0xaa, 0xe4, 0xb2, 0x82, 0xb0, 0xf2, 0x5e, 0x14, 0xac, 0xbc, 0x32, 0x01, 0x56, + 0x86, 0xe4, 0x30, 0x5c, 0xf9, 0x30, 0x1a, 0x57, 0x5e, 0x9b, 0x88, 0x2b, 0xb9, 0xac, 0x30, 0xb0, + 0x7c, 0x2b, 0x00, 0x2c, 0x5f, 0x89, 0x01, 0x96, 0x9c, 0x91, 0x20, 0xcb, 0xf7, 0x47, 0x90, 0x65, + 0x75, 0x1c, 0xb2, 0xe4, 0x9c, 0x3e, 0xb4, 0x6c, 0x44, 0x42, 0xcb, 0xab, 0x93, 0xa0, 0xa5, 0x98, + 0x79, 0x41, 0x6c, 0xf9, 0x38, 0x06, 0x5b, 0x5e, 0x9f, 0x8c, 0x2d, 0xb9, 0xb8, 0x21, 0x70, 0xa9, + 0x8c, 0x05, 0x97, 0x6f, 0x4d, 0x09, 0x2e, 0xb9, 0xec, 0x28, 0x74, 0xf9, 0xff, 0xc3, 0xe8, 0x72, + 0x35, 0x1e, 0x5d, 0x72, 0x21, 0x1c, 0x5e, 0x36, 0x22, 0xe1, 0xe5, 0xd5, 0x49, 0xf0, 0x52, 0x28, + 0x2d, 0x88, 0x2f, 0x1f, 0x46, 0xe3, 0xcb, 0x6b, 0x13, 0xf1, 0xa5, 0x98, 0x3b, 0x21, 0x80, 0xd9, + 0x88, 0x04, 0x98, 0x57, 0x27, 0x01, 0x4c, 0xdf, 0x9a, 0x01, 0x84, 0xb9, 0x1b, 0x8b, 0x30, 0x5f, + 0x9f, 0x06, 0x61, 0x72, 0x91, 0x23, 0x10, 0xf3, 0xe9, 0x14, 0x10, 0xf3, 0xd6, 0x89, 0x20, 0x26, + 0x6f, 0x29, 0x1e, 0x63, 0x7e, 0x12, 0x8f, 0x31, 0xdf, 0x98, 0x0a, 0x63, 0x0a, 0xe7, 0x36, 0x02, + 0x32, 0x6f, 0x85, 0x40, 0xe6, 0x4a, 0x2c, 0xc8, 0x14, 0xbe, 0x96, 0xa2, 0xcc, 0xf7, 0x47, 0x50, + 0x66, 0x75, 0x1c, 0xca, 0x14, 0x0b, 0x56, 0xc0, 0x4c, 0x65, 0x2c, 0x2c, 0x7c, 0x6b, 0x4a, 0x58, + 0x28, 0x16, 0x45, 0x04, 0x2e, 0xac, 0x47, 0xe0, 0xc2, 0xcb, 0xe3, 0x71, 0xa1, 0xd8, 0x0b, 0x07, + 0xc0, 0xf0, 0x5e, 0x14, 0x30, 0xbc, 0x32, 0x01, 0x18, 0x0a, 0xd7, 0x1a, 0x40, 0x86, 0x77, 0x86, + 0x90, 0xe1, 0xa5, 0x89, 0x41, 0x05, 0x1f, 0x1a, 0x7e, 0x30, 0x0a, 0x0d, 0x5f, 0x1d, 0x0b, 0x0d, + 0x39, 0xff, 0x00, 0x1b, 0xde, 0x19, 0xc2, 0x86, 0x97, 0xc6, 0x60, 0x43, 0xd1, 0x38, 0x07, 0x87, + 0x7b, 0xe3, 0xc1, 0x61, 0x6d, 0x5a, 0x70, 0xc8, 0xc5, 0x46, 0xa2, 0xc3, 0x87, 0xd1, 0xe8, 0xf0, + 0xda, 0x94, 0x97, 0xa4, 0x43, 0xf0, 0xf0, 0x5e, 0x14, 0x3c, 0xbc, 0x32, 0x01, 0x1e, 0x0e, 0x36, + 0xc3, 0x28, 0x7c, 0x78, 0x3f, 0x93, 0xbb, 0x58, 0x7e, 0xa5, 0xfa, 0xcb, 0x0c, 0xcc, 0x6c, 0x8b, + 0x98, 0x46, 0xe0, 0x2d, 0x05, 0xe9, 0x34, 0x6f, 0x29, 0xa0, 0x0d, 0x98, 0xe5, 0xca, 0xe4, 0x98, + 0x71, 0xcc, 0xab, 0x57, 0x23, 0x2f, 0xe0, 0x08, 0xd6, 0x53, 0x26, 0xc4, 0xa1, 0x3b, 0x50, 0xea, + 0xbb, 0xd8, 0x51, 0x6c, 0xc7, 0xb0, 0x1c, 0xc3, 0x63, 0x11, 0x5f, 0x69, 0x7d, 0x91, 0xbf, 0x37, + 0x57, 0xdc, 0x75, 0xb1, 0xb3, 0xc3, 0xcb, 0xe4, 0x62, 0x3f, 0xf0, 0x24, 0x3e, 0x67, 0x93, 0x9d, + 0xfe, 0x73, 0x36, 0x4f, 0xa0, 0xec, 0x60, 0x55, 0x0f, 0xb9, 0x2d, 0x96, 0xde, 0x1f, 0xed, 0xd0, + 0x55, 0x3d, 0xe0, 0x9b, 0x02, 0x89, 0x9d, 0xf3, 0x4e, 0xb8, 0x08, 0x7d, 0x07, 0xce, 0xf5, 0xd4, + 0x23, 0xf6, 0xf6, 0x8a, 0xd8, 0x7c, 0x68, 0xa4, 0x27, 0x17, 0x08, 0x1a, 0xa2, 0x9e, 0x7a, 0x44, + 0xbf, 0x93, 0xc3, 0x2a, 0xd0, 0xaf, 0x09, 0xbc, 0x01, 0x73, 0xba, 0xe1, 0x7a, 0x86, 0xa9, 0x89, + 0x77, 0x65, 0xf3, 0xc1, 0x64, 0x76, 0x51, 0xc6, 0x5e, 0x8a, 0xbd, 0x01, 0x0b, 0xfc, 0x0b, 0x05, + 0x83, 0x2f, 0xe7, 0x50, 0xac, 0x96, 0x1b, 0xf4, 0x8b, 0x14, 0x0f, 0x3e, 0x3c, 0xb4, 0x05, 0xf3, + 0x6d, 0xd5, 0xc3, 0x87, 0xea, 0xb1, 0x62, 0x5a, 0x3a, 0xb5, 0x4d, 0x81, 0xbe, 0x58, 0xb6, 0xc2, + 0x6d, 0x53, 0xda, 0x62, 0xc5, 0x8f, 0x2c, 0x9d, 0x59, 0x68, 0x86, 0xfd, 0x93, 0x4b, 0xed, 0x40, + 0x81, 0x7e, 0x3f, 0x93, 0x9b, 0x2d, 0xe7, 0xaa, 0x7f, 0x22, 0x41, 0x31, 0x14, 0x64, 0xff, 0xee, + 0xd0, 0xfd, 0xf9, 0x85, 0x68, 0x80, 0x16, 0x1d, 0x8b, 0xb8, 0x0b, 0x39, 0xae, 0x2b, 0x11, 0x8d, + 0x58, 0x89, 0xdf, 0xa3, 0xe9, 0x61, 0x48, 0x84, 0x62, 0x04, 0xdb, 0xbb, 0x99, 0x3f, 0xfd, 0x62, + 0xe5, 0x4c, 0xf5, 0x17, 0x69, 0x28, 0x85, 0xa3, 0xea, 0x8d, 0xa1, 0x7e, 0x45, 0xad, 0xe0, 0x10, + 0x47, 0x7c, 0x2f, 0x37, 0x20, 0xef, 0xf0, 0x4a, 0xa2, 0x9b, 0xab, 0x63, 0xa2, 0x04, 0xc1, 0x7e, + 0x0e, 0x18, 0x97, 0xfe, 0x36, 0xe5, 0xaf, 0xd8, 0x1a, 0x64, 0xe9, 0xf7, 0xae, 0x78, 0xd7, 0xa2, + 0x72, 0xea, 0x36, 0x49, 0xb9, 0xcc, 0xaa, 0x91, 0x15, 0xde, 0x3a, 0xd5, 0x7b, 0x48, 0x3e, 0xe1, + 0x14, 0x1f, 0x7e, 0x3a, 0xe5, 0x8b, 0x33, 0x4d, 0x72, 0x90, 0xec, 0x76, 0xb1, 0xe6, 0xf1, 0x6f, + 0x64, 0x89, 0x0f, 0x3b, 0x5d, 0x1e, 0x16, 0xc1, 0xbf, 0xa8, 0x55, 0x93, 0xf9, 0x17, 0xb5, 0x02, + 0x01, 0xa2, 0x39, 0x5f, 0x04, 0x9d, 0xf6, 0x2c, 0x22, 0xc8, 0x4c, 0xfd, 0xfa, 0x43, 0x38, 0x1b, + 0xb1, 0x2c, 0xd1, 0x1c, 0x40, 0xfd, 0xf1, 0xa3, 0x66, 0xa3, 0xd9, 0xda, 0x7c, 0xd4, 0x2a, 0x9f, + 0x41, 0x25, 0xc8, 0x93, 0xe7, 0xcd, 0x47, 0xcd, 0xdd, 0x66, 0x59, 0x42, 0x65, 0x28, 0x36, 0x1e, + 0x05, 0x2a, 0xa4, 0x96, 0x32, 0xbf, 0xff, 0xe3, 0xe5, 0x33, 0xaf, 0x3f, 0x81, 0x42, 0xe0, 0x1d, + 0x1e, 0x84, 0x60, 0x6e, 0x67, 0xb7, 0xb9, 0xad, 0xb4, 0x1a, 0x1f, 0x6e, 0x36, 0x5b, 0x77, 0x3f, + 0xdc, 0x29, 0x9f, 0x21, 0x92, 0x29, 0xed, 0xee, 0xfa, 0x63, 0xb9, 0x55, 0x96, 0xfc, 0xe7, 0xd6, + 0xe3, 0xdd, 0xfa, 0x76, 0x39, 0xe5, 0x3f, 0x7f, 0xb4, 0xbb, 0x29, 0x7f, 0xbf, 0x9c, 0xe6, 0x82, + 0xef, 0x00, 0x0c, 0xb2, 0xc1, 0x49, 0x9d, 0x01, 0xd8, 0x2a, 0x9f, 0x41, 0x39, 0xc8, 0x10, 0x14, + 0x53, 0x96, 0xd0, 0x0c, 0xa4, 0x36, 0xac, 0x72, 0x0a, 0xe5, 0x21, 0x5b, 0xef, 0x62, 0xd5, 0x29, + 0xa7, 0x5f, 0x57, 0xe1, 0x5c, 0x64, 0xce, 0x19, 0x2a, 0xc0, 0xec, 0xae, 0x49, 0xdf, 0x3c, 0x61, + 0x03, 0xf4, 0x93, 0x9e, 0xca, 0x12, 0x91, 0xb8, 0xed, 0x79, 0x76, 0x39, 0x45, 0x24, 0x36, 0x6f, + 0x95, 0xd3, 0x68, 0x1e, 0x0a, 0x81, 0xac, 0xad, 0x72, 0x86, 0x34, 0x41, 0x93, 0x79, 0xca, 0xd9, + 0x9b, 0x9f, 0x40, 0x4e, 0xbc, 0xce, 0x8f, 0x1e, 0x42, 0x96, 0xe1, 0x82, 0x95, 0xf8, 0x25, 0x42, + 0x17, 0xdb, 0xd2, 0xea, 0xa4, 0x35, 0x54, 0x3d, 0x43, 0x24, 0x6f, 0x1e, 0x7d, 0x13, 0x92, 0xd7, + 0x2f, 0x7d, 0xf9, 0xf3, 0xe5, 0x33, 0x5f, 0xbe, 0x58, 0x96, 0x7e, 0xfa, 0x62, 0x59, 0xfa, 0xd9, + 0x8b, 0x65, 0xe9, 0xdf, 0x5f, 0x2c, 0x4b, 0x7f, 0xf4, 0x1f, 0xcb, 0x67, 0x3e, 0x9d, 0xe5, 0x2c, + 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0x10, 0x12, 0x4d, 0x5a, 0xb3, 0x4e, 0x00, 0x00, } diff --git a/pkg/roachpb/api.proto b/pkg/roachpb/api.proto index 86e713004fdd..e7056bc70491 100644 --- a/pkg/roachpb/api.proto +++ b/pkg/roachpb/api.proto @@ -604,6 +604,18 @@ message QueryTxnResponse { repeated bytes waiting_txns = 3 [(gogoproto.customtype) = "github.com/cockroachdb/cockroach/pkg/util/uuid.UUID"]; } + +enum PoisonType { + // Sender is at an older version and uses the deprecated_poison field. + Deprecated = 0; + // Make no changes to the abort cache of the associated transaction. + Noop = 1; + // Poison the abort cache of the associated transaction. + Do = 2; + // Clear any entry in the abort cache of the associated transaction. + Clear = 3; +} + // A ResolveIntentRequest is arguments to the ResolveIntent() // method. It is sent by transaction coordinators after success // calling PushTxn to clean up write intents: either to remove, commit @@ -618,7 +630,10 @@ message ResolveIntentRequest { optional TransactionStatus status = 3 [(gogoproto.nullable) = false]; // Optionally poison the sequence cache for the transaction the intent's // range. - optional bool poison = 4 [(gogoproto.nullable) = false]; + // + // TODO(tschottdorf): this can be removed in CockroachDB v1.3. + optional bool deprecated_poison = 4 [(gogoproto.nullable) = false]; + optional PoisonType poison = 5 [(gogoproto.nullable) = false];; } // A ResolveIntentResponse is the return value from the @@ -641,7 +656,10 @@ message ResolveIntentRangeRequest { optional TransactionStatus status = 3 [(gogoproto.nullable) = false]; // Optionally poison the sequence cache for the transaction on all ranges // on which the intents reside. - optional bool poison = 4 [(gogoproto.nullable) = false]; + // + // TODO(tschottdorf): this can be removed in CockroachDB v1.3. + optional bool deprecated_poison = 4 [(gogoproto.nullable) = false]; + optional PoisonType poison = 5 [(gogoproto.nullable) = false]; } // A NoopResponse is the return value from a no-op operation. diff --git a/pkg/storage/gc_queue.go b/pkg/storage/gc_queue.go index 2e5a0054c81b..b633b4c97159 100644 --- a/pkg/storage/gc_queue.go +++ b/pkg/storage/gc_queue.go @@ -408,8 +408,9 @@ func processLocalKeyRange( if err := func() error { infoMu.Unlock() // intentional defer infoMu.Lock() + // This transaction has committed, so poisoning is not relevant. return resolveIntents(roachpb.AsIntents(txn.Intents, &txn), - ResolveOptions{Wait: true, Poison: false}) + ResolveOptions{Wait: true, Poison: roachpb.PoisonType_Noop}) }(); err != nil { // Ignore above error, but if context is expired, no point in keeping going. if ctx.Err() != nil { @@ -424,7 +425,8 @@ func processLocalKeyRange( if err := func() error { infoMu.Unlock() // intentional defer infoMu.Lock() - return resolveIntents(roachpb.AsIntents(txn.Intents, &txn), ResolveOptions{Wait: true, Poison: false}) + // Contention between transactions is not a problem in this path, so use Clear. + return resolveIntents(roachpb.AsIntents(txn.Intents, &txn), ResolveOptions{Wait: true, Poison: roachpb.PoisonType_Clear}) }(); err != nil { // Returning the error here would abort the whole GC run, and // we don't want that. Instead, we simply don't GC this entry. @@ -898,7 +900,14 @@ func RunGC( } } - if err := resolveIntentsFn(intents, ResolveOptions{Wait: true, Poison: false}); err != nil { + // Note that we resolve with PoisonType_NOOP, meaning "leave the abort cache alone". This is + // helpful because it causes less command queue overlap between the various batches the intent + // resolver partitions our intents into (when many of the intents belong to the same + // transaction). The abort cache is cleared out below, so we're not missing anything major here. + // + // TODO(tschottdorf): the intent resolver *could* be smarter here and remember what it already + // cleared. Doubt it's worth it. + if err := resolveIntentsFn(intents, ResolveOptions{Wait: true, Poison: roachpb.PoisonType_Noop}); err != nil { return nil, GCInfo{}, err } diff --git a/pkg/storage/intent_resolver.go b/pkg/storage/intent_resolver.go index 94ccd90cdc3e..034a157aa379 100644 --- a/pkg/storage/intent_resolver.go +++ b/pkg/storage/intent_resolver.go @@ -105,8 +105,16 @@ func (ir *intentResolver) processWriteIntentError( return pErr } + // If we're pushing the other transaction's timestamp, we don't need to touch the abort cache. + // If we abort, we do. Note that we never clear out the cache here, which would be dangerous as + // it could let an aborted-but-running transaction access keys that formerly held its intents. + poisonType := roachpb.PoisonType_Noop + if pushType == roachpb.PUSH_ABORT { + poisonType = roachpb.PoisonType_Do + } + if err := ir.resolveIntents(ctx, resolveIntents, - ResolveOptions{Wait: false, Poison: pushType == roachpb.PUSH_ABORT}); err != nil { + ResolveOptions{Wait: false, Poison: poisonType}); err != nil { return roachpb.NewError(err) } @@ -322,9 +330,10 @@ func (ir *intentResolver) processIntents( // time of writing has our push abort it, leading to the // same situation as above. // - // Thus, we must poison. + // Thus, we must poison (but note that this only has effects + // for those intents which are actually aborted). if err := ir.resolveIntents(ctxWithTimeout, resolveIntents, - ResolveOptions{Wait: true, Poison: true}); err != nil { + ResolveOptions{Wait: true, Poison: roachpb.PoisonType_Do}); err != nil { log.Warningf(ctx, "%s: failed to resolve intents: %s", r, err) return } @@ -334,7 +343,9 @@ func (ir *intentResolver) processIntents( } } else { // EndTransaction // For EndTransaction, we know the transaction is finalized so - // we can skip the push and go straight to the resolve. + // we can skip the push and go straight to the resolve, clearing + // out the abort cache (for intents that are ABORTED, so for a + // successful commit, none). // // This mechanism assumes that when an EndTransaction fails, // the client makes no assumptions about the result. For @@ -342,7 +353,7 @@ func (ir *intentResolver) processIntents( // may succeed (triggering this code path), but the result may // not make it back to the client. if err := ir.resolveIntents(ctxWithTimeout, item.intents, - ResolveOptions{Wait: true, Poison: false}); err != nil { + ResolveOptions{Wait: true, Poison: roachpb.PoisonType_Clear}); err != nil { log.Warningf(ctx, "%s: failed to resolve intents: %s", r, err) return } @@ -365,7 +376,7 @@ func (ir *intentResolver) processIntents( // at least KeyLocalMax. // // #7880 will address this by making GCRequest less special and - // thus obviating the need to cook up an artificial range here. + // thus obviates the need to cook up an artificial range here. var gcArgs roachpb.GCRequest { key := keys.MustAddr(txn.Key) @@ -396,7 +407,7 @@ func (ir *intentResolver) processIntents( // call to block, and whether the ranges containing the intents are to be poisoned. type ResolveOptions struct { Wait bool - Poison bool + Poison roachpb.PoisonType } // resolveIntents resolves the given intents. `wait` is currently a @@ -428,6 +439,8 @@ func (ir *intentResolver) resolveIntents( defer cleanup() log.Eventf(ctx, "resolving intents [wait=%t]", opts.Wait) + var deprecatedPoison = opts.Poison == roachpb.PoisonType_Do + var reqs []roachpb.Request for i := range intents { intent := intents[i] // avoids a race in `i, intent := range ...` @@ -435,17 +448,19 @@ func (ir *intentResolver) resolveIntents( { if len(intent.EndKey) == 0 { resolveArgs = &roachpb.ResolveIntentRequest{ - Span: intent.Span, - IntentTxn: intent.Txn, - Status: intent.Status, - Poison: opts.Poison, + Span: intent.Span, + IntentTxn: intent.Txn, + Status: intent.Status, + DeprecatedPoison: deprecatedPoison, + Poison: opts.Poison, } } else { resolveArgs = &roachpb.ResolveIntentRangeRequest{ - Span: intent.Span, - IntentTxn: intent.Txn, - Status: intent.Status, - Poison: opts.Poison, + Span: intent.Span, + IntentTxn: intent.Txn, + Status: intent.Status, + DeprecatedPoison: deprecatedPoison, + Poison: opts.Poison, } } } diff --git a/pkg/storage/replica_command.go b/pkg/storage/replica_command.go index ac157f719834..8171b815d938 100644 --- a/pkg/storage/replica_command.go +++ b/pkg/storage/replica_command.go @@ -1807,17 +1807,29 @@ func setAbortCache( batch engine.ReadWriter, ms *enginepb.MVCCStats, txn enginepb.TxnMeta, - poison bool, + poisonType roachpb.PoisonType, ) error { - if !poison { + switch poisonType { + case roachpb.PoisonType_Clear: return rec.AbortCache().Del(ctx, batch, ms, txn.ID) + case roachpb.PoisonType_Do: + entry := roachpb.AbortCacheEntry{ + Key: txn.Key, + Timestamp: txn.Timestamp, + Priority: txn.Priority, + } + return rec.AbortCache().Put(ctx, batch, ms, txn.ID, &entry) + case roachpb.PoisonType_Noop: + return nil + default: + return errors.Errorf("unhandled PoisonType: %d", poisonType) } - entry := roachpb.AbortCacheEntry{ - Key: txn.Key, - Timestamp: txn.Timestamp, - Priority: txn.Priority, - } - return rec.AbortCache().Put(ctx, batch, ms, txn.ID, &entry) +} + +func writesAbortCache(intentStatus roachpb.TransactionStatus, poisonType roachpb.PoisonType) bool { + return (intentStatus == roachpb.ABORTED && poisonType == roachpb.PoisonType_Do) || + poisonType == roachpb.PoisonType_Clear + } func declareKeysResolveIntent( @@ -1825,7 +1837,22 @@ func declareKeysResolveIntent( ) { DefaultDeclareKeys(desc, header, req, spans) ri := req.(*roachpb.ResolveIntentRequest) - spans.Add(SpanReadWrite, roachpb.Span{Key: keys.AbortCacheKey(header.RangeID, ri.IntentTxn.ID)}) + + if writesAbortCache(ri.Status, ri.Poison) { + spans.Add(SpanReadWrite, roachpb.Span{Key: keys.AbortCacheKey(header.RangeID, ri.IntentTxn.ID)}) + } +} + +func fromDeprecatedPoison(poison roachpb.PoisonType, deprecatedPoison bool) roachpb.PoisonType { + if poison != roachpb.PoisonType_Deprecated { + return poison + } + if deprecatedPoison { + poison = roachpb.PoisonType_Do + } else { + poison = roachpb.PoisonType_Clear + } + return poison } // evalResolveIntent resolves a write intent from the specified key @@ -1834,23 +1861,27 @@ func evalResolveIntent( ctx context.Context, batch engine.ReadWriter, cArgs CommandArgs, resp roachpb.Response, ) (EvalResult, error) { args := cArgs.Args.(*roachpb.ResolveIntentRequest) + poison := fromDeprecatedPoison(args.Poison, args.DeprecatedPoison) + intent := roachpb.Intent{ + Span: args.Span, + Txn: args.IntentTxn, + Status: args.Status, + } + args = nil // avoid accidental use below + h := cArgs.Header + ms := cArgs.Stats if h.Txn != nil { return EvalResult{}, errTransactionUnsupported } - intent := roachpb.Intent{ - Span: args.Span, - Txn: args.IntentTxn, - Status: args.Status, - } if err := engine.MVCCResolveWriteIntent(ctx, batch, ms, intent); err != nil { return EvalResult{}, err } if intent.Status == roachpb.ABORTED { - return EvalResult{}, setAbortCache(ctx, cArgs.EvalCtx, batch, ms, args.IntentTxn, args.Poison) + return EvalResult{}, setAbortCache(ctx, cArgs.EvalCtx, batch, ms, intent.Txn, poison) } return EvalResult{}, nil } @@ -1860,7 +1891,9 @@ func declareKeysResolveIntentRange( ) { DefaultDeclareKeys(desc, header, req, spans) ri := req.(*roachpb.ResolveIntentRangeRequest) - spans.Add(SpanReadWrite, roachpb.Span{Key: keys.AbortCacheKey(header.RangeID, ri.IntentTxn.ID)}) + if writesAbortCache(ri.Status, ri.Poison) { + spans.Add(SpanReadWrite, roachpb.Span{Key: keys.AbortCacheKey(header.RangeID, ri.IntentTxn.ID)}) + } } // evalResolveIntentRange resolves write intents in the specified @@ -1869,6 +1902,8 @@ func evalResolveIntentRange( ctx context.Context, batch engine.ReadWriter, cArgs CommandArgs, resp roachpb.Response, ) (EvalResult, error) { args := cArgs.Args.(*roachpb.ResolveIntentRangeRequest) + args.Poison = fromDeprecatedPoison(args.Poison, args.DeprecatedPoison) + h := cArgs.Header ms := cArgs.Stats diff --git a/pkg/storage/replica_command_test.go b/pkg/storage/replica_command_test.go new file mode 100644 index 000000000000..944d4a36772d --- /dev/null +++ b/pkg/storage/replica_command_test.go @@ -0,0 +1,90 @@ +// Copyright 2017 The Cockroach Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. See the License for the specific language governing +// permissions and limitations under the License. + +package storage + +import ( + "strings" + "testing" + + "github.com/cockroachdb/cockroach/pkg/roachpb" + "github.com/cockroachdb/cockroach/pkg/storage/engine/enginepb" + "github.com/cockroachdb/cockroach/pkg/util/leaktest" +) + +func TestDeclareKeysResolveIntent(t *testing.T) { + defer leaktest.AfterTest(t)() + + txnMeta := enginepb.TxnMeta{} + desc := roachpb.RangeDescriptor{ + RangeID: 99, + StartKey: roachpb.RKey("a"), + EndKey: roachpb.RKey("a"), + } + for _, test := range []struct { + status roachpb.TransactionStatus + poison roachpb.PoisonType + expSpans []string + }{ + { + status: roachpb.ABORTED, + poison: roachpb.PoisonType_Noop, + expSpans: []string{"1 0: {b-c}"}, + }, + { + status: roachpb.ABORTED, + poison: roachpb.PoisonType_Clear, + expSpans: []string{"1 0: {b-c}", `1 1: /{Local/RangeID/99/r/AbortCache/"00000000-0000-0000-0000-000000000000"-Min}`}, + }, + { + status: roachpb.ABORTED, + poison: roachpb.PoisonType_Do, + expSpans: []string{"1 0: {b-c}", `1 1: /{Local/RangeID/99/r/AbortCache/"00000000-0000-0000-0000-000000000000"-Min}`}, + }, + { + status: roachpb.COMMITTED, + poison: roachpb.PoisonType_Noop, + expSpans: []string{"1 0: {b-c}"}, + }, + { + status: roachpb.COMMITTED, + poison: roachpb.PoisonType_Clear, + expSpans: []string{"1 0: {b-c}", `1 1: /{Local/RangeID/99/r/AbortCache/"00000000-0000-0000-0000-000000000000"-Min}`}, + }, + { + status: roachpb.COMMITTED, + poison: roachpb.PoisonType_Do, + expSpans: []string{"1 0: {b-c}"}, + }, + } { + t.Run("", func(t *testing.T) { + ri := roachpb.ResolveIntentRequest{ + IntentTxn: txnMeta, + Status: test.status, + Poison: test.poison, + } + ri.Key = roachpb.Key("b") + ri.EndKey = roachpb.Key("c") + + var spans SpanSet + var h roachpb.Header + h.RangeID = desc.RangeID + declareKeysResolveIntent(desc, h, &ri, &spans) + exp := strings.Join(test.expSpans, "\n") + if s := strings.TrimSpace(spans.String()); s != exp { + t.Errorf("expected %s, got %s", exp, s) + } + }) + } +} diff --git a/pkg/storage/replica_test.go b/pkg/storage/replica_test.go index 9bace772a0a3..32b19aeccb8c 100644 --- a/pkg/storage/replica_test.go +++ b/pkg/storage/replica_test.go @@ -2511,6 +2511,10 @@ func TestReplicaCommandQueueCancellationLocal(t *testing.T) { }, IntentTxn: txn.TxnMeta, Status: roachpb.PENDING, + // NB: in reality, a timestamp push as this one would specify + // PoisonType_Noop, but this test predates that change and wants + // something that results in the abort cache key to be declared. + Poison: roachpb.PoisonType_Clear, }) getKeyBa := newBa(true /* withTxn */) @@ -4877,7 +4881,7 @@ func TestReplicaResolveIntentNoWait(t *testing.T) { Span: roachpb.Span{Key: key}, Txn: txn.TxnMeta, Status: txn.Status, - }}, ResolveOptions{Wait: false, Poison: false}); pErr != nil { + }}, ResolveOptions{Wait: false, Poison: roachpb.PoisonType_Clear}); pErr != nil { t.Fatal(pErr) } testutils.SucceedsSoon(t, func() error { diff --git a/pkg/storage/span_set.go b/pkg/storage/span_set.go index 2823e44a0a75..746b0848424c 100644 --- a/pkg/storage/span_set.go +++ b/pkg/storage/span_set.go @@ -16,6 +16,9 @@ package storage import ( + "bytes" + "fmt" + "github.com/cockroachdb/cockroach/pkg/keys" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage/engine" @@ -51,6 +54,19 @@ type SpanSet struct { spans [numSpanAccess][numSpanScope][]roachpb.Span } +// String prints a string representation of the span set. +func (ss *SpanSet) String() string { + var buf bytes.Buffer + for i := SpanAccess(0); i < numSpanAccess; i++ { + for j := spanScope(0); j < numSpanScope; j++ { + for _, span := range ss.getSpans(i, j) { + fmt.Fprintf(&buf, "%d %d: %s\n", i, j, span) + } + } + } + return buf.String() +} + func (ss *SpanSet) len() int { var count int for i := SpanAccess(0); i < numSpanAccess; i++ {