From d2876e0ae479c3656262c7ed59715352de72ddc2 Mon Sep 17 00:00:00 2001 From: Manish R Jain Date: Thu, 28 Jun 2018 18:25:42 -0700 Subject: [PATCH] All Oracle delta streams are applied via proposals. (#2463) We should stop having leaders and followers receive transaction status updates from Zero directly and apply them to their state. This causes multiple race conditions and the behavior becomes indeterministic with edge cases. Instead, we have the leaders receive the updates, and propose them to their corresponding group. Proposals flow through Raft and get applied via `Node.Run` in a serial manner. - Only print connection failure once, not every run. - Directly propose OracleDelta, instead of proposing one TxnContext per entry in OracleDelta. - Batch up multiple OracleDelta receives from Zero into one with smart batching into one proposal to the group. This would amortize the cost of proposals. - Remove unnecessary trace: "In run mutation" --- conn/pool.go | 22 +- contrib/integration/acctupsert/main.go | 2 +- dgraph/cmd/server/http.go | 2 + dgraph/cmd/server/run_test.go | 8 +- dgraph/docker-compose.yml | 24 +- edgraph/server.go | 1 + posting/mvcc.go | 3 + protos/intern/internal.pb.go | 520 ++++++++++++++----------- protos/internal.proto | 4 +- worker/draft.go | 57 ++- worker/groups.go | 181 ++++++--- worker/mutation.go | 21 +- 12 files changed, 502 insertions(+), 343 deletions(-) diff --git a/conn/pool.go b/conn/pool.go index dd770e6a36d..c75eac1a40e 100644 --- a/conn/pool.go +++ b/conn/pool.go @@ -123,7 +123,7 @@ func NewPool(addr string) (*Pool, error) { return nil, err } pl := &Pool{conn: conn, Addr: addr, lastEcho: time.Now()} - pl.UpdateHealthStatus() + pl.UpdateHealthStatus(true) // Initialize ticker before running monitor health. pl.ticker = time.NewTicker(echoDuration) @@ -143,7 +143,7 @@ func (p *Pool) shutdown() { p.conn.Close() } -func (p *Pool) UpdateHealthStatus() { +func (p *Pool) UpdateHealthStatus(printError bool) error { conn := p.Get() query := new(api.Payload) @@ -152,23 +152,27 @@ func (p *Pool) UpdateHealthStatus() { c := intern.NewRaftClient(conn) resp, err := c.Echo(context.Background(), query) - var lastEcho time.Time if err == nil { x.AssertTruef(bytes.Equal(resp.Data, query.Data), "non-matching Echo response value from %v", p.Addr) - lastEcho = time.Now() - } else { + p.Lock() + p.lastEcho = time.Now() + p.Unlock() + } else if printError { x.Printf("Echo error from %v. Err: %v\n", p.Addr, err) } - p.Lock() - p.lastEcho = lastEcho - p.Unlock() + return err } // MonitorHealth monitors the health of the connection via Echo. This function blocks forever. func (p *Pool) MonitorHealth() { + var lastErr error for range p.ticker.C { - p.UpdateHealthStatus() + err := p.UpdateHealthStatus(lastErr == nil) + if lastErr != nil && err == nil { + x.Printf("Connection established with %v\n", p.Addr) + } + lastErr = err } } diff --git a/contrib/integration/acctupsert/main.go b/contrib/integration/acctupsert/main.go index fb89645c403..2b000e1675d 100644 --- a/contrib/integration/acctupsert/main.go +++ b/contrib/integration/acctupsert/main.go @@ -26,7 +26,7 @@ import ( var ( addr = flag.String("addr", "localhost:9080", "dgraph address") - concurr = flag.Int("c", 5, "number of concurrent upserts per account") + concurr = flag.Int("c", 3, "number of concurrent upserts per account") ) var ( diff --git a/dgraph/cmd/server/http.go b/dgraph/cmd/server/http.go index af054b1b1a4..a77998a36c8 100644 --- a/dgraph/cmd/server/http.go +++ b/dgraph/cmd/server/http.go @@ -106,6 +106,8 @@ func queryHandler(w http.ResponseWriter, r *http.Request) { d := r.URL.Query().Get("debug") ctx := context.WithValue(context.Background(), "debug", d) + + // Core processing happens here. resp, err := (&edgraph.Server{}).Query(ctx, &req) if err != nil { x.SetStatusWithData(w, x.ErrorInvalidRequest, err.Error()) diff --git a/dgraph/cmd/server/run_test.go b/dgraph/cmd/server/run_test.go index 102e69ce940..725a4fcf9c6 100644 --- a/dgraph/cmd/server/run_test.go +++ b/dgraph/cmd/server/run_test.go @@ -128,7 +128,13 @@ func alterSchema(s string) error { } func alterSchemaWithRetry(s string) error { - return alterSchema(s) + var err error + for i := 0; i < 3; i++ { + if err = alterSchema(s); err == nil { + return nil + } + } + return err } func dropAll() error { diff --git a/dgraph/docker-compose.yml b/dgraph/docker-compose.yml index 021584d5bbe..7c00ccb74ab 100644 --- a/dgraph/docker-compose.yml +++ b/dgraph/docker-compose.yml @@ -17,9 +17,9 @@ services: source: $GOPATH/bin target: /gobin read_only: true - - type: bind - source: "${DATA}" - target: /data + # - type: bind + # source: "${DATA}" + # target: /data # zero2: # image: debian:latest # container_name: bank-dg0.2 @@ -47,9 +47,9 @@ services: source: $GOPATH/bin target: /gobin read_only: true - - type: bind - source: "${DATA}" - target: /data + # - type: bind + # source: "${DATA}" + # target: /data ports: - 8180:8180 - 9180:9180 @@ -63,9 +63,9 @@ services: source: $GOPATH/bin target: /gobin read_only: true - - type: bind - source: "${DATA}" - target: /data + # - type: bind + # source: "${DATA}" + # target: /data ports: - 8181:8181 - 9181:9181 @@ -80,9 +80,9 @@ services: source: $GOPATH/bin target: /gobin read_only: true - - type: bind - source: "${DATA}" - target: /data + # - type: bind + # source: "${DATA}" + # target: /data ports: - 8182:8182 - 9182:9182 diff --git a/edgraph/server.go b/edgraph/server.go index 6403a1bbb82..18d103d5b6e 100644 --- a/edgraph/server.go +++ b/edgraph/server.go @@ -450,6 +450,7 @@ func (s *Server) Query(ctx context.Context, req *api.Request) (resp *api.Respons LinRead: req.LinRead, } + // Core processing happens here. var er query.ExecuteResult if er, err = queryRequest.Process(ctx); err != nil { if tr, ok := trace.FromContext(ctx); ok { diff --git a/posting/mvcc.go b/posting/mvcc.go index 4486c0948a3..23ff10f6af7 100644 --- a/posting/mvcc.go +++ b/posting/mvcc.go @@ -44,6 +44,9 @@ func Txns() *transactions { return txns } +// This structure is useful to keep track of which keys were updated, and whether they should be +// used for conflict detection or not. When a txn is marked committed or aborted, this is what we +// use to go fetch the posting lists and update the txn status in them. type delta struct { key []byte posting *intern.Posting diff --git a/protos/intern/internal.pb.go b/protos/intern/internal.pb.go index 2af0f5b9e71..6d947a0999e 100644 --- a/protos/intern/internal.pb.go +++ b/protos/intern/internal.pb.go @@ -1131,13 +1131,14 @@ func (m *KeyValues) GetKv() []*KV { } type Proposal struct { - DeprecatedId uint32 `protobuf:"varint,1,opt,name=deprecated_id,json=deprecatedId,proto3" json:"deprecated_id,omitempty"` - Mutations *Mutations `protobuf:"bytes,2,opt,name=mutations" json:"mutations,omitempty"` - TxnContext *api.TxnContext `protobuf:"bytes,3,opt,name=txn_context,json=txnContext" json:"txn_context,omitempty"` - Kv []*KV `protobuf:"bytes,4,rep,name=kv" json:"kv,omitempty"` - State *MembershipState `protobuf:"bytes,5,opt,name=state" json:"state,omitempty"` - CleanPredicate string `protobuf:"bytes,6,opt,name=clean_predicate,json=cleanPredicate,proto3" json:"clean_predicate,omitempty"` - Key string `protobuf:"bytes,7,opt,name=key,proto3" json:"key,omitempty"` + DeprecatedId uint32 `protobuf:"varint,1,opt,name=deprecated_id,json=deprecatedId,proto3" json:"deprecated_id,omitempty"` + DeprecatedTxnContext *api.TxnContext `protobuf:"bytes,3,opt,name=deprecated_txn_context,json=deprecatedTxnContext" json:"deprecated_txn_context,omitempty"` + Mutations *Mutations `protobuf:"bytes,2,opt,name=mutations" json:"mutations,omitempty"` + Kv []*KV `protobuf:"bytes,4,rep,name=kv" json:"kv,omitempty"` + State *MembershipState `protobuf:"bytes,5,opt,name=state" json:"state,omitempty"` + CleanPredicate string `protobuf:"bytes,6,opt,name=clean_predicate,json=cleanPredicate,proto3" json:"clean_predicate,omitempty"` + Key string `protobuf:"bytes,7,opt,name=key,proto3" json:"key,omitempty"` + Delta *OracleDelta `protobuf:"bytes,8,opt,name=delta" json:"delta,omitempty"` } func (m *Proposal) Reset() { *m = Proposal{} } @@ -1152,16 +1153,16 @@ func (m *Proposal) GetDeprecatedId() uint32 { return 0 } -func (m *Proposal) GetMutations() *Mutations { +func (m *Proposal) GetDeprecatedTxnContext() *api.TxnContext { if m != nil { - return m.Mutations + return m.DeprecatedTxnContext } return nil } -func (m *Proposal) GetTxnContext() *api.TxnContext { +func (m *Proposal) GetMutations() *Mutations { if m != nil { - return m.TxnContext + return m.Mutations } return nil } @@ -1194,6 +1195,13 @@ func (m *Proposal) GetKey() string { return "" } +func (m *Proposal) GetDelta() *OracleDelta { + if m != nil { + return m.Delta + } + return nil +} + type KVS struct { Kv []*KV `protobuf:"bytes,1,rep,name=kv" json:"kv,omitempty"` } @@ -4079,11 +4087,11 @@ func (m *Proposal) MarshalTo(dAtA []byte) (int, error) { } i += n20 } - if m.TxnContext != nil { + if m.DeprecatedTxnContext != nil { dAtA[i] = 0x1a i++ - i = encodeVarintInternal(dAtA, i, uint64(m.TxnContext.Size())) - n21, err := m.TxnContext.MarshalTo(dAtA[i:]) + i = encodeVarintInternal(dAtA, i, uint64(m.DeprecatedTxnContext.Size())) + n21, err := m.DeprecatedTxnContext.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -4123,6 +4131,16 @@ func (m *Proposal) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintInternal(dAtA, i, uint64(len(m.Key))) i += copy(dAtA[i:], m.Key) } + if m.Delta != nil { + dAtA[i] = 0x42 + i++ + i = encodeVarintInternal(dAtA, i, uint64(m.Delta.Size())) + n23, err := m.Delta.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n23 + } return i, nil } @@ -4535,11 +4553,11 @@ func (m *FilterTree) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintInternal(dAtA, i, uint64(m.Func.Size())) - n23, err := m.Func.MarshalTo(dAtA[i:]) + n24, err := m.Func.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n24 } return i, nil } @@ -4747,11 +4765,11 @@ func (m *MapEntry) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintInternal(dAtA, i, uint64(m.Posting.Size())) - n24, err := m.Posting.MarshalTo(dAtA[i:]) + n25, err := m.Posting.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n25 } return i, nil } @@ -4791,11 +4809,11 @@ func (m *MovePredicatePayload) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintInternal(dAtA, i, uint64(m.State.Size())) - n25, err := m.State.MarshalTo(dAtA[i:]) + n26, err := m.State.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n26 } return i, nil } @@ -4869,21 +4887,21 @@ func (m *OracleDelta) MarshalTo(dAtA []byte) (int, error) { } } if len(m.Aborts) > 0 { - dAtA27 := make([]byte, len(m.Aborts)*10) - var j26 int + dAtA28 := make([]byte, len(m.Aborts)*10) + var j27 int for _, num := range m.Aborts { for num >= 1<<7 { - dAtA27[j26] = uint8(uint64(num)&0x7f | 0x80) + dAtA28[j27] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j26++ + j27++ } - dAtA27[j26] = uint8(num) - j26++ + dAtA28[j27] = uint8(num) + j27++ } dAtA[i] = 0x12 i++ - i = encodeVarintInternal(dAtA, i, uint64(j26)) - i += copy(dAtA[i:], dAtA27[:j26]) + i = encodeVarintInternal(dAtA, i, uint64(j27)) + i += copy(dAtA[i:], dAtA28[:j27]) } if m.MaxPending != 0 { dAtA[i] = 0x18 @@ -4909,21 +4927,21 @@ func (m *TxnTimestamps) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if len(m.Ts) > 0 { - dAtA29 := make([]byte, len(m.Ts)*10) - var j28 int + dAtA30 := make([]byte, len(m.Ts)*10) + var j29 int for _, num := range m.Ts { for num >= 1<<7 { - dAtA29[j28] = uint8(uint64(num)&0x7f | 0x80) + dAtA30[j29] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j28++ + j29++ } - dAtA29[j28] = uint8(num) - j28++ + dAtA30[j29] = uint8(num) + j29++ } dAtA[i] = 0xa i++ - i = encodeVarintInternal(dAtA, i, uint64(j28)) - i += copy(dAtA[i:], dAtA29[:j28]) + i = encodeVarintInternal(dAtA, i, uint64(j29)) + i += copy(dAtA[i:], dAtA30[:j29]) } return i, nil } @@ -5542,8 +5560,8 @@ func (m *Proposal) Size() (n int) { l = m.Mutations.Size() n += 1 + l + sovInternal(uint64(l)) } - if m.TxnContext != nil { - l = m.TxnContext.Size() + if m.DeprecatedTxnContext != nil { + l = m.DeprecatedTxnContext.Size() n += 1 + l + sovInternal(uint64(l)) } if len(m.Kv) > 0 { @@ -5564,6 +5582,10 @@ func (m *Proposal) Size() (n int) { if l > 0 { n += 1 + l + sovInternal(uint64(l)) } + if m.Delta != nil { + l = m.Delta.Size() + n += 1 + l + sovInternal(uint64(l)) + } return n } @@ -9714,7 +9736,7 @@ func (m *Proposal) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TxnContext", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeprecatedTxnContext", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9738,10 +9760,10 @@ func (m *Proposal) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.TxnContext == nil { - m.TxnContext = &api.TxnContext{} + if m.DeprecatedTxnContext == nil { + m.DeprecatedTxnContext = &api.TxnContext{} } - if err := m.TxnContext.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.DeprecatedTxnContext.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -9867,6 +9889,39 @@ func (m *Proposal) Unmarshal(dAtA []byte) error { } m.Key = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Delta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Delta == nil { + m.Delta = &OracleDelta{} + } + if err := m.Delta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipInternal(dAtA[iNdEx:]) @@ -12729,194 +12784,195 @@ var ( func init() { proto.RegisterFile("internal.proto", fileDescriptorInternal) } var fileDescriptorInternal = []byte{ - // 3014 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x19, 0xcb, 0x72, 0x23, 0x57, - 0x55, 0xdd, 0x6a, 0xb5, 0x5a, 0x47, 0x92, 0x47, 0xb9, 0x99, 0xcc, 0x28, 0x4a, 0x70, 0x9c, 0x9e, - 0x90, 0x71, 0x5e, 0x4e, 0xc6, 0x99, 0x3c, 0x18, 0x08, 0x94, 0x63, 0x69, 0x26, 0xca, 0xf8, 0x95, - 0x2b, 0xd9, 0x21, 0x2c, 0x50, 0x5d, 0xab, 0xaf, 0xe5, 0x2e, 0xb7, 0xba, 0x3b, 0x7d, 0xbb, 0x5d, - 0x72, 0x96, 0xec, 0x28, 0x76, 0xac, 0xb2, 0xa6, 0x8a, 0x1d, 0x55, 0x54, 0xb1, 0x64, 0xc1, 0x0a, - 0xaa, 0x58, 0x50, 0x05, 0xfc, 0x01, 0x84, 0x0d, 0xc5, 0x8e, 0x3f, 0xa0, 0xee, 0xa3, 0x1f, 0x92, - 0x35, 0x8e, 0x79, 0xad, 0xd4, 0xe7, 0xdc, 0x73, 0xee, 0xe3, 0xbc, 0xcf, 0x11, 0xac, 0xb8, 0x7e, - 0x4c, 0x23, 0x9f, 0x78, 0x1b, 0x61, 0x14, 0xc4, 0x01, 0x32, 0x25, 0xdc, 0xa9, 0x91, 0xd0, 0x95, - 0x28, 0xbb, 0x03, 0xc6, 0x8e, 0xcb, 0x62, 0x84, 0xc0, 0x48, 0x5c, 0x87, 0xb5, 0xb5, 0xb5, 0xf2, - 0xba, 0x89, 0xc5, 0xb7, 0xfd, 0x09, 0xd4, 0x86, 0x84, 0x9d, 0x1d, 0x11, 0x2f, 0xa1, 0xa8, 0x05, - 0xe5, 0x73, 0xe2, 0xb5, 0xb5, 0x35, 0x6d, 0xbd, 0x81, 0xf9, 0x27, 0xda, 0x04, 0xeb, 0x9c, 0x78, - 0xa3, 0xf8, 0x22, 0xa4, 0x6d, 0x7d, 0x4d, 0x5b, 0x5f, 0xd9, 0xbc, 0xbd, 0x21, 0x0f, 0xd8, 0x38, - 0x08, 0x58, 0xec, 0xfa, 0x93, 0x8d, 0x23, 0xe2, 0x0d, 0x2f, 0x42, 0x8a, 0xab, 0xe7, 0xf2, 0xc3, - 0xde, 0x87, 0xfa, 0x20, 0x1a, 0x3f, 0x4c, 0xfc, 0x71, 0xec, 0x06, 0x3e, 0x3f, 0xd5, 0x27, 0x53, - 0x2a, 0x76, 0xad, 0x61, 0xf1, 0xcd, 0x71, 0x24, 0x9a, 0xb0, 0x76, 0x79, 0xad, 0xcc, 0x71, 0xfc, - 0x1b, 0xb5, 0xa1, 0xea, 0xb2, 0xed, 0x20, 0xf1, 0xe3, 0xb6, 0xb1, 0xa6, 0xad, 0x5b, 0x38, 0x05, - 0xed, 0x5f, 0x94, 0xa1, 0xf2, 0x49, 0x42, 0xa3, 0x0b, 0xc1, 0x17, 0xc7, 0x51, 0xba, 0x17, 0xff, - 0x46, 0x37, 0xa1, 0xe2, 0x11, 0x7f, 0xc2, 0xda, 0xba, 0xd8, 0x4c, 0x02, 0xe8, 0x39, 0xa8, 0x91, - 0x93, 0x98, 0x46, 0xa3, 0xc4, 0x75, 0xda, 0xe5, 0x35, 0x6d, 0xdd, 0xc4, 0x96, 0x40, 0x1c, 0xba, - 0x0e, 0x7a, 0x16, 0x2c, 0x27, 0x18, 0x8d, 0x8b, 0x67, 0x39, 0x81, 0x38, 0x0b, 0xdd, 0x05, 0x2b, - 0x71, 0x9d, 0x91, 0xe7, 0xb2, 0xb8, 0x5d, 0x59, 0xd3, 0xd6, 0xeb, 0x9b, 0x8d, 0xf4, 0xc1, 0x5c, - 0x86, 0xb8, 0x9a, 0xb8, 0x8e, 0x10, 0xe6, 0x06, 0x58, 0x2c, 0x1a, 0x8f, 0x4e, 0x12, 0x7f, 0xdc, - 0x36, 0x05, 0xe1, 0xd3, 0x29, 0x61, 0xe1, 0xf5, 0xb8, 0xca, 0x24, 0xc0, 0x9f, 0x17, 0xd1, 0x73, - 0x1a, 0x31, 0xda, 0xae, 0xca, 0x23, 0x15, 0x88, 0xee, 0x43, 0xfd, 0x84, 0x8c, 0x69, 0x3c, 0x0a, - 0x49, 0x44, 0xa6, 0x6d, 0x6b, 0x7e, 0xb3, 0x87, 0x7c, 0xe9, 0x80, 0xaf, 0x30, 0x0c, 0x27, 0x19, - 0x80, 0xde, 0x83, 0xa6, 0x80, 0xd8, 0xe8, 0xc4, 0xf5, 0x62, 0x1a, 0xb5, 0x6b, 0x82, 0x0f, 0x65, - 0x7c, 0x02, 0x3b, 0x8c, 0x28, 0xc5, 0x0d, 0x49, 0x28, 0x31, 0xe8, 0x1b, 0x00, 0x74, 0x16, 0x12, - 0xdf, 0x19, 0x11, 0xcf, 0x6b, 0x83, 0xb8, 0x4b, 0x4d, 0x62, 0xb6, 0x3c, 0x0f, 0xdd, 0xe6, 0xf7, - 0x24, 0xce, 0x28, 0x66, 0xed, 0xe6, 0x9a, 0xb6, 0x6e, 0x60, 0x93, 0x83, 0x43, 0xc6, 0x25, 0xe3, - 0xb9, 0xfe, 0x88, 0x43, 0xed, 0x15, 0x25, 0x19, 0x6e, 0x63, 0x3b, 0xae, 0x8f, 0x29, 0x71, 0x70, - 0xd5, 0x93, 0x1f, 0xf6, 0xbb, 0x50, 0x13, 0xe6, 0x24, 0xc4, 0xf4, 0x0a, 0x98, 0xe7, 0x1c, 0x90, - 0x56, 0x57, 0xdf, 0x7c, 0x2a, 0xbd, 0x5f, 0x66, 0x75, 0x58, 0x11, 0xd8, 0xab, 0x60, 0xed, 0x10, - 0x7f, 0x92, 0x9a, 0x2a, 0xd7, 0xa3, 0x60, 0xaa, 0x61, 0xf1, 0x6d, 0xff, 0x59, 0x07, 0x13, 0x53, - 0x96, 0x78, 0x31, 0x7a, 0x0d, 0x80, 0x6b, 0x69, 0x4a, 0xe2, 0xc8, 0x9d, 0xa9, 0x9d, 0xe7, 0xf5, - 0x54, 0x4b, 0x5c, 0x67, 0x57, 0x2c, 0xa3, 0xfb, 0xd0, 0x10, 0x27, 0xa4, 0xe4, 0xfa, 0xfc, 0x45, - 0xb2, 0xbb, 0xe2, 0xba, 0x20, 0x53, 0x5c, 0xb7, 0xc0, 0x14, 0x06, 0x22, 0x8d, 0xb4, 0x89, 0x15, - 0x84, 0xbe, 0xa9, 0x3c, 0x8e, 0xd1, 0x71, 0x3c, 0x72, 0x28, 0x4b, 0x2d, 0xa8, 0x99, 0x61, 0xbb, - 0x94, 0xc5, 0xe8, 0x1d, 0x90, 0x52, 0x4f, 0x0f, 0xad, 0x88, 0x43, 0xd1, 0x9c, 0x56, 0x99, 0x3c, - 0x55, 0xd0, 0xa9, 0x53, 0xef, 0x41, 0x9d, 0xbf, 0x35, 0xe5, 0x32, 0x05, 0x57, 0x2b, 0x7b, 0x99, - 0x12, 0x0f, 0x06, 0x4e, 0xa4, 0x58, 0xb8, 0xa8, 0xb8, 0xb5, 0x4a, 0xab, 0x12, 0xdf, 0xd7, 0xd7, - 0x55, 0x0f, 0x2a, 0xfb, 0x91, 0x43, 0xa3, 0xa5, 0x9e, 0x85, 0xc0, 0x70, 0x28, 0x1b, 0x0b, 0xc7, - 0xb7, 0xb0, 0xf8, 0xce, 0xbd, 0xad, 0x5c, 0xf0, 0x36, 0xfb, 0x8f, 0x1a, 0xd4, 0x07, 0x41, 0x14, - 0xef, 0x52, 0xc6, 0xc8, 0x84, 0xa2, 0x3b, 0x50, 0x09, 0xf8, 0xb6, 0x4a, 0x35, 0xcd, 0xf4, 0x01, - 0xe2, 0x2c, 0x2c, 0xd7, 0x16, 0x94, 0xa8, 0x5f, 0xad, 0xc4, 0x9b, 0x50, 0x91, 0xfe, 0xca, 0x7d, - 0xb9, 0x82, 0x25, 0xc0, 0x95, 0x14, 0x9c, 0x9c, 0x30, 0x2a, 0x95, 0x50, 0xc1, 0x0a, 0xfa, 0x1f, - 0x18, 0xf1, 0x31, 0x00, 0x7f, 0xd0, 0x7f, 0x62, 0x6f, 0xd7, 0x3e, 0xe3, 0x14, 0xea, 0x98, 0x9c, - 0xc4, 0xdb, 0x81, 0x1f, 0xd3, 0x59, 0x8c, 0x56, 0x40, 0x77, 0x1d, 0xa1, 0x00, 0x13, 0xeb, 0xae, - 0xc3, 0x9f, 0x3c, 0x89, 0x82, 0x24, 0x14, 0xf2, 0x6f, 0x62, 0x09, 0x08, 0x45, 0x39, 0x4e, 0x24, - 0xe4, 0xc0, 0x15, 0xe5, 0x38, 0x11, 0x7a, 0x01, 0xea, 0xcc, 0x27, 0x21, 0x3b, 0x0d, 0x62, 0xfe, - 0x64, 0x43, 0x3c, 0x19, 0x52, 0xd4, 0x90, 0xd9, 0xbf, 0xd3, 0xc0, 0xdc, 0xa5, 0xd3, 0x63, 0x1a, - 0x5d, 0x3a, 0xe5, 0x59, 0xb0, 0xc4, 0xc6, 0x23, 0xd7, 0x51, 0x07, 0x55, 0x05, 0xdc, 0x77, 0x96, - 0x1e, 0x75, 0x0b, 0x4c, 0x8f, 0x12, 0xae, 0x5a, 0x69, 0xf6, 0x0a, 0xe2, 0x12, 0x27, 0xd3, 0x91, - 0xc3, 0xdf, 0x5c, 0x91, 0x0b, 0x64, 0xda, 0xa5, 0xc4, 0xe1, 0x77, 0xf3, 0x08, 0x8b, 0x47, 0x49, - 0xe8, 0x90, 0x98, 0x8a, 0x50, 0x69, 0x70, 0xfb, 0x65, 0xf1, 0xa1, 0xc0, 0xa0, 0x57, 0xe1, 0xa9, - 0xb1, 0x97, 0x30, 0x1e, 0xab, 0x5d, 0xff, 0x24, 0x18, 0x05, 0xbe, 0x77, 0x21, 0xb4, 0x66, 0xe1, - 0x1b, 0x6a, 0xa1, 0xef, 0x9f, 0x04, 0xfb, 0xbe, 0x77, 0x61, 0xff, 0x44, 0x87, 0xca, 0x23, 0x21, - 0x86, 0xfb, 0x50, 0x9d, 0x8a, 0x07, 0xa5, 0x81, 0xa5, 0x93, 0xaa, 0x43, 0xac, 0x6f, 0xc8, 0xd7, - 0xb2, 0x9e, 0x1f, 0x47, 0x17, 0x38, 0x25, 0xe5, 0x5c, 0x31, 0x39, 0xf6, 0x68, 0xcc, 0x94, 0xbd, - 0x2d, 0x70, 0x0d, 0xe5, 0xa2, 0xe2, 0x52, 0xa4, 0x9d, 0x8f, 0xa1, 0x51, 0xdc, 0x8e, 0xa7, 0xc9, - 0x33, 0x7a, 0x21, 0x64, 0x68, 0x60, 0xfe, 0x89, 0x5e, 0x82, 0x8a, 0x88, 0x1d, 0x42, 0x82, 0xf5, - 0xcd, 0x95, 0x74, 0x57, 0xc9, 0x86, 0xe5, 0xe2, 0x03, 0xfd, 0x7d, 0x8d, 0xef, 0x55, 0x3c, 0xa4, - 0xb8, 0x57, 0xed, 0xea, 0xbd, 0x24, 0x5b, 0x61, 0x2f, 0xfb, 0xa7, 0x3a, 0x34, 0x7e, 0x40, 0xa3, - 0xe0, 0x20, 0x0a, 0xc2, 0x80, 0x11, 0x0f, 0xdd, 0x81, 0xa6, 0x43, 0xc3, 0x88, 0x8e, 0x49, 0x4c, - 0x9d, 0x91, 0x52, 0x73, 0x13, 0x37, 0x72, 0x64, 0xdf, 0x41, 0x2f, 0x83, 0x29, 0xc5, 0xf1, 0x84, - 0xcb, 0xaa, 0x55, 0x4e, 0x27, 0x05, 0x20, 0xf4, 0x7f, 0xf9, 0x22, 0x6a, 0x15, 0xad, 0x02, 0x4c, - 0xc9, 0x6c, 0x87, 0x12, 0x46, 0xfb, 0x4e, 0x6a, 0x7b, 0x39, 0x06, 0x75, 0xc0, 0x9a, 0x92, 0xd9, - 0x70, 0xe6, 0x0f, 0x99, 0x30, 0x0d, 0x03, 0x67, 0x30, 0x7a, 0x1e, 0x6a, 0x53, 0x32, 0xe3, 0x4e, - 0xd0, 0x77, 0x94, 0x69, 0xe4, 0x08, 0xf4, 0x22, 0x94, 0xe3, 0x99, 0x2f, 0x02, 0x5b, 0x7d, 0xf3, - 0x86, 0xf0, 0xa1, 0xe1, 0xcc, 0x57, 0xee, 0x82, 0xf9, 0x5a, 0x2a, 0x3e, 0x2b, 0x13, 0x9f, 0xfd, - 0xeb, 0x32, 0xdc, 0x50, 0xda, 0x3a, 0x75, 0xc3, 0x41, 0xcc, 0x4d, 0xac, 0x0d, 0x55, 0x11, 0x2f, - 0x68, 0xa4, 0x94, 0x96, 0x82, 0xe8, 0xdb, 0x60, 0x0a, 0x6b, 0x4f, 0xed, 0xe1, 0xce, 0xbc, 0x30, - 0xb2, 0x2d, 0xa4, 0x7d, 0x28, 0xc3, 0x50, 0x2c, 0xe8, 0x7d, 0xa8, 0x7c, 0x41, 0xa3, 0x40, 0xc6, - 0xc2, 0xfa, 0xa6, 0xfd, 0x24, 0x5e, 0xae, 0x23, 0xc5, 0x2a, 0x19, 0xfe, 0x8f, 0x32, 0x5b, 0xe7, - 0x91, 0x6f, 0x1a, 0x9c, 0x53, 0xa7, 0x5d, 0x15, 0xb7, 0x5a, 0x54, 0x6f, 0xba, 0xdc, 0xf9, 0x08, - 0xea, 0x85, 0x47, 0x15, 0x0d, 0xb1, 0x29, 0x0d, 0xf1, 0xce, 0xbc, 0x21, 0x36, 0xe7, 0x5c, 0xa5, - 0x68, 0xd3, 0x1f, 0x01, 0xe4, 0x4f, 0xfc, 0x6f, 0xbc, 0xc3, 0xfe, 0xb1, 0x06, 0x37, 0xb6, 0x03, - 0xdf, 0xa7, 0xa2, 0x78, 0x92, 0xca, 0xcb, 0xed, 0x55, 0xbb, 0xd2, 0x5e, 0xdf, 0x80, 0x0a, 0xe3, - 0x0c, 0xea, 0x94, 0xdb, 0x4f, 0xd0, 0x06, 0x96, 0x54, 0x3c, 0x2e, 0x4d, 0xc9, 0x6c, 0x14, 0x52, - 0xdf, 0x71, 0xfd, 0x89, 0xb0, 0x71, 0xa9, 0x83, 0x03, 0x89, 0xb1, 0x7f, 0xa6, 0x81, 0x29, 0x4d, - 0x7d, 0x2e, 0x46, 0x6a, 0xf3, 0x31, 0xf2, 0x79, 0xa8, 0x85, 0x11, 0x75, 0xdc, 0x71, 0x7a, 0x72, - 0x0d, 0xe7, 0x08, 0x1e, 0xc2, 0x4f, 0x82, 0x68, 0x4c, 0xc5, 0xf6, 0x16, 0x96, 0x00, 0xaf, 0x4d, - 0x45, 0x76, 0x12, 0x91, 0x4e, 0x86, 0x51, 0x8b, 0x23, 0x78, 0x88, 0xe3, 0x2c, 0x2c, 0x24, 0x63, - 0x59, 0x25, 0x96, 0xb1, 0x04, 0x78, 0xd8, 0x95, 0x7a, 0x13, 0xa6, 0x6e, 0x61, 0x05, 0xd9, 0xbf, - 0xd2, 0xa1, 0xd1, 0x75, 0x23, 0x3a, 0x8e, 0xa9, 0xd3, 0x73, 0x26, 0x82, 0x90, 0xfa, 0xb1, 0x1b, - 0x5f, 0xa8, 0x10, 0xaf, 0xa0, 0x2c, 0xbf, 0xeb, 0xf3, 0x95, 0xb3, 0xd4, 0x4b, 0x59, 0x14, 0xfc, - 0x12, 0x40, 0xef, 0x02, 0xc8, 0x72, 0x49, 0x14, 0xfd, 0xc6, 0xd5, 0x45, 0x7f, 0x4d, 0x90, 0xf2, - 0x4f, 0x2e, 0x24, 0xc9, 0xe7, 0xca, 0x14, 0x60, 0x8a, 0x8e, 0x20, 0xe1, 0xe6, 0x2c, 0x8a, 0x86, - 0x63, 0xea, 0x09, 0x73, 0x15, 0x45, 0xc3, 0x31, 0xf5, 0xb2, 0x1a, 0xaf, 0x2a, 0xaf, 0xc4, 0xbf, - 0xd1, 0x5d, 0xd0, 0x83, 0x50, 0xbc, 0xb1, 0x70, 0x68, 0xf1, 0x81, 0x1b, 0xfb, 0x21, 0xd6, 0x83, - 0x10, 0xd9, 0x60, 0xca, 0xaa, 0xb6, 0x5d, 0x13, 0x66, 0x0e, 0x22, 0x3c, 0x88, 0xb2, 0x0a, 0xab, - 0x15, 0xfb, 0x16, 0xe8, 0xfb, 0x21, 0xaa, 0x42, 0x79, 0xd0, 0x1b, 0xb6, 0x4a, 0xfc, 0xa3, 0xdb, - 0xdb, 0x69, 0x69, 0xf6, 0x3f, 0x34, 0xa8, 0xed, 0x26, 0x31, 0xe1, 0x36, 0xc6, 0xae, 0x52, 0xee, - 0xb3, 0x60, 0xb1, 0x98, 0x44, 0x22, 0xa9, 0xea, 0x32, 0x70, 0x08, 0x78, 0xc8, 0xd0, 0xab, 0x50, - 0xa1, 0xce, 0x84, 0xa6, 0xbe, 0x7f, 0x73, 0xd9, 0x5d, 0xb1, 0x24, 0x41, 0xaf, 0x83, 0xc9, 0xc6, - 0xa7, 0x74, 0x4a, 0xda, 0xc6, 0x3c, 0xf1, 0x40, 0x60, 0x65, 0x1e, 0xc4, 0x8a, 0x46, 0x34, 0x27, - 0x51, 0x10, 0x8a, 0xea, 0xbc, 0xa2, 0x9a, 0x93, 0x28, 0x08, 0x79, 0x6d, 0xbe, 0x09, 0xcf, 0xb8, - 0x13, 0x3f, 0x88, 0xe8, 0xc8, 0xf5, 0x1d, 0x3a, 0x1b, 0x8d, 0x03, 0xff, 0xc4, 0x73, 0xc7, 0xb1, - 0x90, 0xab, 0x85, 0x9f, 0x96, 0x8b, 0x7d, 0xbe, 0xb6, 0xad, 0x96, 0xec, 0xbb, 0x50, 0x7b, 0x4c, - 0x2f, 0x44, 0x91, 0xcb, 0x50, 0x07, 0xf4, 0xb3, 0x73, 0x95, 0x30, 0x21, 0xbd, 0xc5, 0xe3, 0x23, - 0xac, 0x9f, 0x9d, 0xdb, 0x5f, 0xea, 0x60, 0xfd, 0x7b, 0x99, 0xe4, 0x4d, 0xa8, 0x4d, 0x53, 0x31, - 0x2a, 0xaf, 0xcb, 0xaa, 0xea, 0x4c, 0xbe, 0x38, 0xa7, 0x41, 0x6f, 0x41, 0x3d, 0x9e, 0xf9, 0xfc, - 0xda, 0x3c, 0x82, 0xab, 0xbc, 0x72, 0x29, 0xb0, 0x43, 0x9c, 0x7d, 0xab, 0x0b, 0x1b, 0xcb, 0x2e, - 0x9c, 0x3b, 0x7c, 0xe5, 0x5a, 0x0e, 0x7f, 0x17, 0x6e, 0x8c, 0x3d, 0x4a, 0xfc, 0x51, 0xee, 0xaf, - 0xd2, 0x1c, 0x57, 0x04, 0xfa, 0x20, 0x73, 0x5a, 0x15, 0xc0, 0xaa, 0x79, 0x4e, 0x79, 0x11, 0xca, - 0x8f, 0x8f, 0x06, 0x57, 0x4a, 0xef, 0x87, 0xa0, 0x3f, 0x3e, 0x2a, 0xc6, 0xbe, 0x86, 0x8c, 0x7d, - 0xaa, 0xa5, 0xd6, 0xf3, 0x96, 0xba, 0x03, 0x56, 0xc2, 0x68, 0xb4, 0x4b, 0x63, 0xa2, 0x1c, 0x2f, - 0x83, 0x79, 0xa2, 0xe2, 0x3d, 0xa1, 0x1b, 0xf8, 0x2a, 0x29, 0xa4, 0xa0, 0xfd, 0xcf, 0x32, 0x54, - 0x95, 0xf3, 0xf1, 0x3d, 0x93, 0xac, 0x86, 0xe3, 0x9f, 0xb9, 0x27, 0xeb, 0x45, 0x4f, 0x2e, 0x36, - 0xef, 0xe5, 0xeb, 0x35, 0xef, 0xe8, 0xbb, 0xd0, 0x08, 0xe5, 0x5a, 0xd1, 0xff, 0x9f, 0x5b, 0xe4, - 0x53, 0xbf, 0x82, 0xb7, 0x1e, 0xe6, 0x00, 0xb7, 0x5e, 0xd1, 0xc0, 0xc4, 0x64, 0x22, 0xf4, 0xd2, - 0xc0, 0x55, 0x0e, 0x0f, 0xc9, 0xe4, 0x09, 0x51, 0xe0, 0x1a, 0x8e, 0xcc, 0x6b, 0xd6, 0x20, 0x6c, - 0x37, 0x84, 0x09, 0x72, 0xe7, 0x2f, 0xfa, 0x65, 0x73, 0xde, 0x2f, 0x9f, 0x83, 0xda, 0x38, 0x98, - 0x4e, 0x5d, 0xb1, 0xb6, 0x22, 0x53, 0xa7, 0x44, 0x0c, 0x99, 0xfd, 0x05, 0x54, 0xd5, 0x83, 0x51, - 0x1d, 0xaa, 0xdd, 0xde, 0xc3, 0xad, 0xc3, 0x1d, 0x1e, 0x19, 0x00, 0xcc, 0x0f, 0xfb, 0x7b, 0x5b, - 0xf8, 0xb3, 0x96, 0xc6, 0xa3, 0x44, 0x7f, 0x6f, 0xd8, 0xd2, 0x51, 0x0d, 0x2a, 0x0f, 0x77, 0xf6, - 0xb7, 0x86, 0xad, 0x32, 0xb2, 0xc0, 0xf8, 0x70, 0x7f, 0x7f, 0xa7, 0x65, 0xa0, 0x06, 0x58, 0xdd, - 0xad, 0x61, 0x6f, 0xd8, 0xdf, 0xed, 0xb5, 0x2a, 0x9c, 0xf6, 0x51, 0x6f, 0xbf, 0x65, 0xf2, 0x8f, - 0xc3, 0x7e, 0xb7, 0x55, 0xe5, 0xeb, 0x07, 0x5b, 0x83, 0xc1, 0xa7, 0xfb, 0xb8, 0xdb, 0xb2, 0xf8, - 0xbe, 0x83, 0x21, 0xee, 0xef, 0x3d, 0x6a, 0xd5, 0xec, 0x7b, 0x50, 0x2f, 0x08, 0x8d, 0x73, 0xe0, - 0xde, 0xc3, 0x56, 0x89, 0x1f, 0x73, 0xb4, 0xb5, 0x73, 0xd8, 0x6b, 0x69, 0x68, 0x05, 0x40, 0x7c, - 0x8e, 0x76, 0xb6, 0xf6, 0x1e, 0xb5, 0x74, 0xfb, 0x47, 0x5a, 0xc6, 0x23, 0x9a, 0xe2, 0xd7, 0xc0, - 0x52, 0xa2, 0x4e, 0x8b, 0xde, 0x1b, 0x0b, 0x7a, 0xc1, 0x19, 0x01, 0x37, 0xb3, 0xf1, 0x29, 0x1d, - 0x9f, 0xb1, 0x64, 0xaa, 0xac, 0x22, 0x83, 0x65, 0x6f, 0xcb, 0x65, 0xa2, 0xd2, 0x9e, 0x82, 0xb2, - 0x01, 0x91, 0x21, 0xe8, 0xe5, 0x80, 0xe8, 0x3e, 0x40, 0x3e, 0x82, 0x58, 0x52, 0xae, 0xde, 0x84, - 0x0a, 0xf1, 0x5c, 0xc2, 0x54, 0x66, 0x91, 0x80, 0x8d, 0xa1, 0x5e, 0x18, 0x5c, 0x70, 0x85, 0x11, - 0xcf, 0x1b, 0x9d, 0xd1, 0x0b, 0x26, 0x78, 0x2d, 0x5c, 0x25, 0x9e, 0xf7, 0x98, 0x5e, 0x30, 0xb4, - 0x0e, 0x15, 0x39, 0xf7, 0xd0, 0x97, 0x74, 0xc8, 0x82, 0x1d, 0x4b, 0x02, 0xfb, 0x75, 0x30, 0x65, - 0xdb, 0x5c, 0xb0, 0x19, 0xed, 0x89, 0xc1, 0xff, 0x03, 0x75, 0x6f, 0xd1, 0x64, 0xa3, 0x37, 0xd5, - 0x8c, 0x85, 0xc9, 0xc9, 0x8e, 0x36, 0x5f, 0x1a, 0x49, 0x42, 0x35, 0x5e, 0x11, 0x0c, 0x76, 0x17, - 0xac, 0x2b, 0x27, 0x58, 0x4a, 0x10, 0x7a, 0x2e, 0x88, 0x25, 0x33, 0x2d, 0x3b, 0x02, 0xc8, 0xe7, - 0x30, 0xca, 0x8c, 0xe5, 0x2e, 0xdc, 0x8c, 0x37, 0xb8, 0x8a, 0x5c, 0xcf, 0x89, 0xa8, 0x7f, 0xe9, - 0xf5, 0xf9, 0xf4, 0x26, 0xa3, 0x41, 0x2f, 0x81, 0x21, 0xc6, 0x4d, 0x32, 0x6e, 0x66, 0x53, 0x81, - 0x6c, 0xd6, 0x24, 0x56, 0xed, 0x63, 0x68, 0xca, 0xbc, 0x82, 0xe9, 0xe7, 0x09, 0x65, 0x57, 0x56, - 0x2f, 0xab, 0x00, 0x59, 0x34, 0x4c, 0x07, 0x68, 0x05, 0x0c, 0x37, 0x94, 0x13, 0x97, 0x7a, 0x4e, - 0xfa, 0x2a, 0x05, 0xd9, 0xef, 0x41, 0x23, 0x3d, 0x43, 0xf4, 0xc7, 0x77, 0xb3, 0x0c, 0x97, 0xda, - 0x25, 0x57, 0x88, 0x24, 0xd9, 0x0b, 0x9c, 0x2c, 0xb9, 0xd9, 0x7f, 0xd5, 0x53, 0x4e, 0xd5, 0xfd, - 0xcd, 0xd5, 0x4f, 0xda, 0x62, 0xfd, 0x34, 0x5f, 0x8b, 0xe8, 0xd7, 0xae, 0x45, 0xbe, 0x03, 0x35, - 0x47, 0x24, 0x62, 0xf7, 0x3c, 0x0d, 0x7d, 0xab, 0xcb, 0x92, 0xae, 0x4a, 0xd7, 0xee, 0x39, 0xc5, - 0x39, 0x03, 0xbf, 0x53, 0x1c, 0x9c, 0x51, 0xdf, 0xfd, 0x42, 0xb4, 0xb9, 0xfc, 0xe1, 0x39, 0x22, - 0x9f, 0x44, 0xc8, 0xe4, 0xac, 0x26, 0x11, 0xe9, 0x14, 0xc6, 0x2c, 0x4c, 0x61, 0x6e, 0x81, 0x99, - 0x84, 0x8c, 0x46, 0x71, 0x5a, 0xb4, 0x49, 0x28, 0x2b, 0x7c, 0x6a, 0x8a, 0x96, 0xf8, 0x13, 0xfb, - 0x5b, 0x50, 0xcb, 0xee, 0xc2, 0xe3, 0xcd, 0xde, 0xfe, 0x5e, 0x4f, 0x46, 0x87, 0xfe, 0x5e, 0xb7, - 0xf7, 0xfd, 0x96, 0xc6, 0x23, 0x16, 0xee, 0x1d, 0xf5, 0xf0, 0xa0, 0xd7, 0xd2, 0x79, 0x64, 0xe9, - 0xf6, 0x76, 0x7a, 0xc3, 0x5e, 0xab, 0xfc, 0xb1, 0x61, 0x55, 0x5b, 0x16, 0xb6, 0xe8, 0x2c, 0xf4, - 0xdc, 0xb1, 0x1b, 0xdb, 0x9f, 0x81, 0xb5, 0x4b, 0xc2, 0x4b, 0xc5, 0x78, 0x9e, 0x90, 0x12, 0xd5, - 0xea, 0xab, 0xe4, 0xf1, 0x0a, 0x54, 0x55, 0xd4, 0xc8, 0x32, 0xf2, 0x42, 0x54, 0x49, 0xd7, 0xed, - 0x5f, 0x6a, 0x70, 0x73, 0x37, 0x38, 0xa7, 0x59, 0xb2, 0x3c, 0x20, 0x17, 0x5e, 0x40, 0x9c, 0xaf, - 0x51, 0xe3, 0xcb, 0x70, 0x83, 0x05, 0x49, 0x34, 0xa6, 0xa3, 0x85, 0x51, 0x43, 0x53, 0xa2, 0x1f, - 0x29, 0x73, 0xb4, 0x79, 0xd5, 0xc1, 0xe2, 0x9c, 0xaa, 0x2c, 0xa8, 0xea, 0x1c, 0x99, 0xd2, 0x64, - 0x59, 0xdf, 0xb8, 0x4e, 0xd6, 0xb7, 0xff, 0xa0, 0x41, 0xb3, 0x37, 0x0b, 0x83, 0x28, 0x4e, 0xaf, - 0xfa, 0x0c, 0x2f, 0xa5, 0x3f, 0x4f, 0x9d, 0xc1, 0xc0, 0x95, 0x88, 0x7e, 0xde, 0xbf, 0x72, 0x0e, - 0x72, 0x1f, 0x4c, 0xbe, 0x59, 0xc2, 0x94, 0x29, 0x3d, 0x9f, 0x9e, 0x39, 0xb7, 0xf1, 0xc6, 0x40, - 0xd0, 0x60, 0x45, 0x5b, 0x9c, 0x41, 0x19, 0xc5, 0x19, 0x94, 0xfd, 0x00, 0x4c, 0x49, 0x5a, 0xd0, - 0x73, 0x1d, 0xaa, 0x83, 0xc3, 0xed, 0xed, 0xde, 0x60, 0xd0, 0xd2, 0x50, 0x13, 0x6a, 0xdd, 0xc3, - 0x83, 0x9d, 0xfe, 0xf6, 0xd6, 0x50, 0xe9, 0xfa, 0xe1, 0x56, 0x7f, 0xa7, 0xd7, 0x6d, 0x95, 0xed, - 0xdf, 0x68, 0x50, 0xdf, 0x8f, 0xc8, 0xd8, 0xa3, 0x5d, 0xea, 0xc5, 0x04, 0x3d, 0xe0, 0x9d, 0x2d, - 0x8f, 0xdd, 0x69, 0x28, 0x5c, 0xcb, 0x47, 0x6d, 0x19, 0xd5, 0xc6, 0xb6, 0x24, 0x51, 0x63, 0x0d, - 0xc5, 0xc0, 0xcd, 0x93, 0x1c, 0x07, 0x91, 0x9a, 0x85, 0x18, 0x58, 0x41, 0x5f, 0xdb, 0x19, 0x75, - 0x1e, 0x40, 0xa3, 0xb8, 0xe3, 0x92, 0x8e, 0x6f, 0xae, 0x1e, 0x31, 0x8a, 0x1d, 0xde, 0x0b, 0xd0, - 0xe4, 0x6d, 0xac, 0x3b, 0xa5, 0x2c, 0x26, 0xd3, 0x50, 0xe4, 0x76, 0x75, 0x79, 0x03, 0xeb, 0x31, - 0xb3, 0x5f, 0x86, 0xc6, 0x01, 0xa5, 0x11, 0xa6, 0x2c, 0x0c, 0x7c, 0x26, 0x1a, 0x1a, 0x25, 0x7c, - 0x99, 0x38, 0x14, 0x64, 0xdf, 0x86, 0xf2, 0x5e, 0x32, 0x2d, 0xfe, 0x65, 0x61, 0x88, 0xfa, 0xca, - 0x7e, 0x08, 0x8d, 0x81, 0x9a, 0x7c, 0x89, 0x9a, 0x8a, 0x57, 0x04, 0x9e, 0x4b, 0x7d, 0x51, 0x11, - 0x68, 0xaa, 0x22, 0x10, 0x88, 0x21, 0xbb, 0x42, 0xeb, 0x9b, 0xbf, 0xd5, 0xc0, 0xe0, 0x4d, 0x35, - 0x0f, 0xbb, 0xbd, 0xf1, 0x69, 0x80, 0xe4, 0x14, 0x4f, 0x69, 0xbb, 0x33, 0x07, 0xd9, 0x25, 0xf4, - 0x9a, 0x1c, 0xe6, 0xa5, 0x13, 0xd0, 0xab, 0x89, 0x37, 0xa1, 0xfe, 0x71, 0xe0, 0xfa, 0xdb, 0x72, - 0xbc, 0x85, 0xb2, 0x61, 0x7f, 0x61, 0x1c, 0x78, 0x89, 0xe7, 0x1d, 0x30, 0xfb, 0x8c, 0x8b, 0x66, - 0x39, 0x79, 0xd6, 0x54, 0x14, 0xa5, 0x67, 0x97, 0x36, 0x7f, 0x5e, 0x06, 0x83, 0x77, 0xe7, 0xe8, - 0x3e, 0x54, 0x55, 0x6b, 0x8d, 0x16, 0x5a, 0xe8, 0x4e, 0xe6, 0x44, 0x0b, 0xbd, 0xb7, 0x5d, 0x42, - 0xef, 0x82, 0xa9, 0x22, 0xf5, 0x7c, 0xff, 0xdf, 0x79, 0x92, 0xe3, 0xd9, 0xa5, 0x75, 0xed, 0x2d, - 0x0d, 0xbd, 0x09, 0xa6, 0xb4, 0xc0, 0x05, 0x49, 0x3c, 0xbd, 0xc4, 0x3e, 0xed, 0x92, 0x60, 0xa8, - 0x0f, 0x4e, 0x83, 0xc4, 0x73, 0x06, 0x34, 0x3a, 0xa7, 0x68, 0x61, 0xda, 0xd4, 0x59, 0x80, 0xed, - 0x12, 0x7a, 0x03, 0x60, 0x8b, 0x31, 0x77, 0xe2, 0x1f, 0xba, 0x0e, 0x43, 0xf5, 0x74, 0x7d, 0x2f, - 0x99, 0x76, 0x5a, 0xe2, 0x48, 0xb9, 0xca, 0x3b, 0x15, 0x26, 0xc9, 0x0b, 0x56, 0xf7, 0xb5, 0xe4, - 0x6f, 0x43, 0x53, 0xda, 0xf8, 0x7e, 0xb4, 0xc5, 0xdd, 0x02, 0x2d, 0xb6, 0x29, 0x9d, 0x45, 0x84, - 0x5d, 0x42, 0x0f, 0xc0, 0x1a, 0x46, 0x17, 0x92, 0xfe, 0x99, 0xec, 0xc2, 0x45, 0x73, 0xef, 0x2c, - 0x47, 0xdb, 0xa5, 0xcd, 0xbf, 0x97, 0xc1, 0xfc, 0x34, 0x88, 0xce, 0x68, 0x84, 0x36, 0xc0, 0x14, - 0xed, 0x13, 0x45, 0x97, 0xdb, 0xa9, 0x65, 0xc7, 0xbe, 0x0e, 0x35, 0x21, 0xb4, 0x21, 0x61, 0x67, - 0xb9, 0x9a, 0xc4, 0x3f, 0x66, 0xb9, 0xdc, 0x64, 0xa6, 0xb6, 0x4b, 0xe8, 0x7b, 0x70, 0x2b, 0x0b, - 0xdf, 0x5b, 0xbe, 0x23, 0xd3, 0x61, 0x97, 0xc4, 0x04, 0xe5, 0x7d, 0x69, 0xc1, 0x7f, 0x3a, 0xf5, - 0xbc, 0xd3, 0x19, 0x08, 0x4d, 0xdd, 0x03, 0x63, 0xc0, 0x5f, 0x98, 0xff, 0xdf, 0x95, 0x4f, 0xfe, - 0x3b, 0xa8, 0x88, 0xcc, 0xce, 0x7c, 0x0f, 0x4c, 0x79, 0x4e, 0x2e, 0x96, 0xb9, 0x1a, 0xa5, 0x73, - 0x73, 0x11, 0xad, 0x18, 0xef, 0x82, 0xb5, 0xeb, 0xfa, 0x72, 0xf0, 0x35, 0x6f, 0x48, 0x45, 0x0d, - 0xda, 0x25, 0xf4, 0x3e, 0x98, 0x32, 0x1a, 0xe7, 0x27, 0xcc, 0x45, 0xe7, 0xce, 0x72, 0xb4, 0x5d, - 0x42, 0xf7, 0xa0, 0x85, 0xe9, 0x98, 0xba, 0x85, 0xac, 0x86, 0x8a, 0x6f, 0x5e, 0x74, 0xc4, 0x75, - 0x0d, 0x7d, 0x00, 0xcd, 0xb9, 0x2c, 0x88, 0xb2, 0x8c, 0xb0, 0x2c, 0x39, 0x2e, 0x6e, 0xf0, 0x61, - 0xeb, 0xf7, 0x5f, 0xad, 0x6a, 0x7f, 0xfa, 0x6a, 0x55, 0xfb, 0xcb, 0x57, 0xab, 0xda, 0x97, 0x7f, - 0x5b, 0x2d, 0x1d, 0x9b, 0xe2, 0x8f, 0xda, 0xb7, 0xff, 0x15, 0x00, 0x00, 0xff, 0xff, 0x1c, 0xcf, - 0xad, 0x21, 0xcd, 0x1d, 0x00, 0x00, + // 3035 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x39, 0x4b, 0x6f, 0x23, 0xc7, + 0xd1, 0x9c, 0x21, 0x39, 0x1c, 0x16, 0x49, 0x2d, 0xdd, 0x5e, 0xef, 0xd2, 0xb4, 0x3f, 0x59, 0xee, + 0xf5, 0xe7, 0x95, 0x5f, 0xf2, 0xb7, 0xf2, 0xfa, 0xf1, 0xed, 0xf7, 0x39, 0x81, 0x2c, 0x52, 0x6b, + 0x7a, 0xf5, 0x72, 0x93, 0x92, 0xe3, 0x1c, 0x42, 0xb4, 0x38, 0x2d, 0x6a, 0xa0, 0xe1, 0xcc, 0x78, + 0x7a, 0x28, 0x50, 0x3e, 0xe6, 0x16, 0xe4, 0x96, 0x53, 0xce, 0x01, 0x72, 0x0b, 0x10, 0x20, 0xc7, + 0x1c, 0x72, 0x4a, 0x80, 0x1c, 0x02, 0x24, 0xb9, 0xe5, 0x98, 0x38, 0x97, 0x20, 0xb7, 0xfc, 0x83, + 0xa0, 0x1f, 0xf3, 0x20, 0xc5, 0x95, 0x95, 0xd7, 0x89, 0x53, 0xd5, 0x55, 0x5d, 0xdd, 0x55, 0xd5, + 0xf5, 0x22, 0xac, 0xb8, 0x7e, 0xcc, 0x22, 0x9f, 0x7a, 0x1b, 0x61, 0x14, 0xc4, 0x01, 0xb2, 0x14, + 0xdc, 0xae, 0xd2, 0xd0, 0x55, 0x28, 0xdc, 0x86, 0xd2, 0xae, 0xcb, 0x63, 0x84, 0xa0, 0x34, 0x75, + 0x1d, 0xde, 0x32, 0xd6, 0x8a, 0xeb, 0x16, 0x91, 0xdf, 0xf8, 0x53, 0xa8, 0x0e, 0x28, 0x3f, 0x3f, + 0xa6, 0xde, 0x94, 0xa1, 0x26, 0x14, 0x2f, 0xa8, 0xd7, 0x32, 0xd6, 0x8c, 0xf5, 0x3a, 0x11, 0x9f, + 0x68, 0x13, 0xec, 0x0b, 0xea, 0x0d, 0xe3, 0xcb, 0x90, 0xb5, 0xcc, 0x35, 0x63, 0x7d, 0x65, 0xf3, + 0xee, 0x86, 0x12, 0xb0, 0x71, 0x18, 0xf0, 0xd8, 0xf5, 0xc7, 0x1b, 0xc7, 0xd4, 0x1b, 0x5c, 0x86, + 0x8c, 0x54, 0x2e, 0xd4, 0x07, 0x3e, 0x80, 0x5a, 0x3f, 0x1a, 0xed, 0x4c, 0xfd, 0x51, 0xec, 0x06, + 0xbe, 0x90, 0xea, 0xd3, 0x09, 0x93, 0xbb, 0x56, 0x89, 0xfc, 0x16, 0x38, 0x1a, 0x8d, 0x79, 0xab, + 0xb8, 0x56, 0x14, 0x38, 0xf1, 0x8d, 0x5a, 0x50, 0x71, 0xf9, 0x76, 0x30, 0xf5, 0xe3, 0x56, 0x69, + 0xcd, 0x58, 0xb7, 0x49, 0x02, 0xe2, 0x9f, 0x14, 0xa1, 0xfc, 0xe9, 0x94, 0x45, 0x97, 0x92, 0x2f, + 0x8e, 0xa3, 0x64, 0x2f, 0xf1, 0x8d, 0x6e, 0x43, 0xd9, 0xa3, 0xfe, 0x98, 0xb7, 0x4c, 0xb9, 0x99, + 0x02, 0xd0, 0x0b, 0x50, 0xa5, 0xa7, 0x31, 0x8b, 0x86, 0x53, 0xd7, 0x69, 0x15, 0xd7, 0x8c, 0x75, + 0x8b, 0xd8, 0x12, 0x71, 0xe4, 0x3a, 0xe8, 0x79, 0xb0, 0x9d, 0x60, 0x38, 0xca, 0xcb, 0x72, 0x02, + 0x29, 0x0b, 0xdd, 0x07, 0x7b, 0xea, 0x3a, 0x43, 0xcf, 0xe5, 0x71, 0xab, 0xbc, 0x66, 0xac, 0xd7, + 0x36, 0xeb, 0xc9, 0x85, 0x85, 0x0e, 0x49, 0x65, 0xea, 0x3a, 0x52, 0x99, 0x1b, 0x60, 0xf3, 0x68, + 0x34, 0x3c, 0x9d, 0xfa, 0xa3, 0x96, 0x25, 0x09, 0x9f, 0x4d, 0x08, 0x73, 0xb7, 0x27, 0x15, 0xae, + 0x00, 0x71, 0xbd, 0x88, 0x5d, 0xb0, 0x88, 0xb3, 0x56, 0x45, 0x89, 0xd4, 0x20, 0x7a, 0x08, 0xb5, + 0x53, 0x3a, 0x62, 0xf1, 0x30, 0xa4, 0x11, 0x9d, 0xb4, 0xec, 0xf9, 0xcd, 0x76, 0xc4, 0xd2, 0xa1, + 0x58, 0xe1, 0x04, 0x4e, 0x53, 0x00, 0xbd, 0x0f, 0x0d, 0x09, 0xf1, 0xe1, 0xa9, 0xeb, 0xc5, 0x2c, + 0x6a, 0x55, 0x25, 0x1f, 0x4a, 0xf9, 0x24, 0x76, 0x10, 0x31, 0x46, 0xea, 0x8a, 0x50, 0x61, 0xd0, + 0x7f, 0x01, 0xb0, 0x59, 0x48, 0x7d, 0x67, 0x48, 0x3d, 0xaf, 0x05, 0xf2, 0x2c, 0x55, 0x85, 0xd9, + 0xf2, 0x3c, 0x74, 0x57, 0x9c, 0x93, 0x3a, 0xc3, 0x98, 0xb7, 0x1a, 0x6b, 0xc6, 0x7a, 0x89, 0x58, + 0x02, 0x1c, 0x70, 0xa1, 0x19, 0xcf, 0xf5, 0x87, 0x02, 0x6a, 0xad, 0x68, 0xcd, 0x08, 0x1f, 0xdb, + 0x75, 0x7d, 0xc2, 0xa8, 0x43, 0x2a, 0x9e, 0xfa, 0xc0, 0xef, 0x41, 0x55, 0xba, 0x93, 0x54, 0xd3, + 0x6b, 0x60, 0x5d, 0x08, 0x40, 0x79, 0x5d, 0x6d, 0xf3, 0x99, 0xe4, 0x7c, 0xa9, 0xd7, 0x11, 0x4d, + 0x80, 0x57, 0xc1, 0xde, 0xa5, 0xfe, 0x38, 0x71, 0x55, 0x61, 0x47, 0xc9, 0x54, 0x25, 0xf2, 0x1b, + 0xff, 0xde, 0x04, 0x8b, 0x30, 0x3e, 0xf5, 0x62, 0xf4, 0x06, 0x80, 0xb0, 0xd2, 0x84, 0xc6, 0x91, + 0x3b, 0xd3, 0x3b, 0xcf, 0xdb, 0xa9, 0x3a, 0x75, 0x9d, 0x3d, 0xb9, 0x8c, 0x1e, 0x42, 0x5d, 0x4a, + 0x48, 0xc8, 0xcd, 0xf9, 0x83, 0xa4, 0x67, 0x25, 0x35, 0x49, 0xa6, 0xb9, 0xee, 0x80, 0x25, 0x1d, + 0x44, 0x39, 0x69, 0x83, 0x68, 0x08, 0xfd, 0xb7, 0x7e, 0x71, 0x9c, 0x8d, 0xe2, 0xa1, 0xc3, 0x78, + 0xe2, 0x41, 0x8d, 0x14, 0xdb, 0x61, 0x3c, 0x46, 0xef, 0x82, 0xd2, 0x7a, 0x22, 0xb4, 0x2c, 0x85, + 0xa2, 0x39, 0xab, 0x72, 0x25, 0x55, 0xd2, 0x69, 0xa9, 0x0f, 0xa0, 0x26, 0xee, 0x9a, 0x70, 0x59, + 0x92, 0xab, 0x99, 0xde, 0x4c, 0xab, 0x87, 0x80, 0x20, 0xd2, 0x2c, 0x42, 0x55, 0xc2, 0x5b, 0x95, + 0x57, 0xc9, 0xef, 0x9b, 0xdb, 0xaa, 0x0b, 0xe5, 0x83, 0xc8, 0x61, 0xd1, 0xd2, 0x97, 0x85, 0xa0, + 0xe4, 0x30, 0x3e, 0x92, 0x0f, 0xdf, 0x26, 0xf2, 0x3b, 0x7b, 0x6d, 0xc5, 0xdc, 0x6b, 0xc3, 0xbf, + 0x35, 0xa0, 0xd6, 0x0f, 0xa2, 0x78, 0x8f, 0x71, 0x4e, 0xc7, 0x0c, 0xdd, 0x83, 0x72, 0x20, 0xb6, + 0xd5, 0xa6, 0x69, 0x24, 0x17, 0x90, 0xb2, 0x88, 0x5a, 0x5b, 0x30, 0xa2, 0x79, 0xbd, 0x11, 0x6f, + 0x43, 0x59, 0xbd, 0x57, 0xf1, 0x96, 0xcb, 0x44, 0x01, 0xc2, 0x48, 0xc1, 0xe9, 0x29, 0x67, 0xca, + 0x08, 0x65, 0xa2, 0xa1, 0x7f, 0x83, 0x13, 0x9f, 0x00, 0x88, 0x0b, 0xfd, 0x33, 0xfe, 0x76, 0x63, + 0x19, 0x67, 0x50, 0x23, 0xf4, 0x34, 0xde, 0x0e, 0xfc, 0x98, 0xcd, 0x62, 0xb4, 0x02, 0xa6, 0xeb, + 0x48, 0x03, 0x58, 0xc4, 0x74, 0x1d, 0x71, 0xe5, 0x71, 0x14, 0x4c, 0x43, 0xa9, 0xff, 0x06, 0x51, + 0x80, 0x34, 0x94, 0xe3, 0x44, 0x52, 0x0f, 0xc2, 0x50, 0x8e, 0x13, 0xa1, 0x97, 0xa0, 0xc6, 0x7d, + 0x1a, 0xf2, 0xb3, 0x20, 0x16, 0x57, 0x2e, 0xc9, 0x2b, 0x43, 0x82, 0x1a, 0x70, 0xfc, 0x2b, 0x03, + 0xac, 0x3d, 0x36, 0x39, 0x61, 0xd1, 0x15, 0x29, 0xcf, 0x83, 0x2d, 0x37, 0x1e, 0xba, 0x8e, 0x16, + 0x54, 0x91, 0x70, 0xcf, 0x59, 0x2a, 0xea, 0x0e, 0x58, 0x1e, 0xa3, 0xc2, 0xb4, 0xca, 0xed, 0x35, + 0x24, 0x34, 0x4e, 0x27, 0x43, 0x47, 0xdc, 0xb9, 0xac, 0x16, 0xe8, 0xa4, 0xc3, 0xa8, 0x23, 0xce, + 0xe6, 0x51, 0x1e, 0x0f, 0xa7, 0xa1, 0x43, 0x63, 0x26, 0x43, 0x65, 0x49, 0xf8, 0x2f, 0x8f, 0x8f, + 0x24, 0x06, 0xbd, 0x0e, 0xcf, 0x8c, 0xbc, 0x29, 0x17, 0xb1, 0xda, 0xf5, 0x4f, 0x83, 0x61, 0xe0, + 0x7b, 0x97, 0xd2, 0x6a, 0x36, 0xb9, 0xa5, 0x17, 0x7a, 0xfe, 0x69, 0x70, 0xe0, 0x7b, 0x97, 0xf8, + 0xfb, 0x26, 0x94, 0x1f, 0x4b, 0x35, 0x3c, 0x84, 0xca, 0x44, 0x5e, 0x28, 0x09, 0x2c, 0xed, 0xc4, + 0x1c, 0x72, 0x7d, 0x43, 0xdd, 0x96, 0x77, 0xfd, 0x38, 0xba, 0x24, 0x09, 0xa9, 0xe0, 0x8a, 0xe9, + 0x89, 0xc7, 0x62, 0xae, 0xfd, 0x6d, 0x81, 0x6b, 0xa0, 0x16, 0x35, 0x97, 0x26, 0x6d, 0x7f, 0x02, + 0xf5, 0xfc, 0x76, 0x22, 0x4d, 0x9e, 0xb3, 0x4b, 0xa9, 0xc3, 0x12, 0x11, 0x9f, 0xe8, 0x15, 0x28, + 0xcb, 0xd8, 0x21, 0x35, 0x58, 0xdb, 0x5c, 0x49, 0x76, 0x55, 0x6c, 0x44, 0x2d, 0x3e, 0x32, 0x3f, + 0x30, 0xc4, 0x5e, 0x79, 0x21, 0xf9, 0xbd, 0xaa, 0xd7, 0xef, 0xa5, 0xd8, 0x72, 0x7b, 0xe1, 0x1f, + 0x98, 0x50, 0xff, 0x36, 0x8b, 0x82, 0xc3, 0x28, 0x08, 0x03, 0x4e, 0x3d, 0x74, 0x0f, 0x1a, 0x0e, + 0x0b, 0x23, 0x36, 0xa2, 0x31, 0x73, 0x86, 0xda, 0xcc, 0x0d, 0x52, 0xcf, 0x90, 0x3d, 0x07, 0xbd, + 0x0a, 0x96, 0x52, 0xc7, 0x53, 0x0e, 0xab, 0x57, 0x05, 0x9d, 0x52, 0x80, 0xb4, 0xff, 0xd5, 0x83, + 0xe8, 0x55, 0xb4, 0x0a, 0x30, 0xa1, 0xb3, 0x5d, 0x46, 0x39, 0xeb, 0x39, 0x89, 0xef, 0x65, 0x18, + 0xd4, 0x06, 0x7b, 0x42, 0x67, 0x83, 0x99, 0x3f, 0xe0, 0xd2, 0x35, 0x4a, 0x24, 0x85, 0xd1, 0x8b, + 0x50, 0x9d, 0xd0, 0x99, 0x78, 0x04, 0x3d, 0x47, 0xbb, 0x46, 0x86, 0x40, 0x2f, 0x43, 0x31, 0x9e, + 0xf9, 0x32, 0xb0, 0xd5, 0x36, 0x6f, 0xc9, 0x37, 0x34, 0x98, 0xf9, 0xfa, 0xb9, 0x10, 0xb1, 0x96, + 0xa8, 0xcf, 0x4e, 0xd5, 0x87, 0x7f, 0x5e, 0x84, 0x5b, 0xda, 0x5a, 0x67, 0x6e, 0xd8, 0x8f, 0x85, + 0x8b, 0xb5, 0xa0, 0x22, 0xe3, 0x05, 0x8b, 0xb4, 0xd1, 0x12, 0x10, 0xfd, 0x1f, 0x58, 0xd2, 0xdb, + 0x13, 0x7f, 0xb8, 0x37, 0xaf, 0x8c, 0x74, 0x0b, 0xe5, 0x1f, 0xda, 0x31, 0x34, 0x0b, 0xfa, 0x00, + 0xca, 0x5f, 0xb2, 0x28, 0x50, 0xb1, 0xb0, 0xb6, 0x89, 0x9f, 0xc6, 0x2b, 0x6c, 0xa4, 0x59, 0x15, + 0xc3, 0x7f, 0x50, 0x67, 0xeb, 0x22, 0xf2, 0x4d, 0x82, 0x0b, 0xe6, 0xb4, 0x2a, 0xf2, 0x54, 0x8b, + 0xe6, 0x4d, 0x96, 0xdb, 0x1f, 0x43, 0x2d, 0x77, 0xa9, 0xbc, 0x23, 0x36, 0x94, 0x23, 0xde, 0x9b, + 0x77, 0xc4, 0xc6, 0xdc, 0x53, 0xc9, 0xfb, 0xf4, 0xc7, 0x00, 0xd9, 0x15, 0xff, 0x95, 0xd7, 0x81, + 0xbf, 0x67, 0xc0, 0xad, 0xed, 0xc0, 0xf7, 0x99, 0x2c, 0x9e, 0x94, 0xf1, 0x32, 0x7f, 0x35, 0xae, + 0xf5, 0xd7, 0xb7, 0xa0, 0xcc, 0x05, 0x83, 0x96, 0x72, 0xf7, 0x29, 0xd6, 0x20, 0x8a, 0x4a, 0xc4, + 0xa5, 0x09, 0x9d, 0x0d, 0x43, 0xe6, 0x3b, 0xae, 0x3f, 0x96, 0x3e, 0xae, 0x6c, 0x70, 0xa8, 0x30, + 0xf8, 0x47, 0x06, 0x58, 0xca, 0xd5, 0xe7, 0x62, 0xa4, 0x31, 0x1f, 0x23, 0x5f, 0x84, 0x6a, 0x18, + 0x31, 0xc7, 0x1d, 0x25, 0x92, 0xab, 0x24, 0x43, 0x88, 0x10, 0x7e, 0x1a, 0x44, 0x23, 0x26, 0xb7, + 0xb7, 0x89, 0x02, 0x44, 0x6d, 0x2a, 0xb3, 0x93, 0x8c, 0x74, 0x2a, 0x8c, 0xda, 0x02, 0x21, 0x42, + 0x9c, 0x60, 0xe1, 0x21, 0x1d, 0xa9, 0x2a, 0xb1, 0x48, 0x14, 0x20, 0xc2, 0xae, 0xb2, 0x9b, 0x74, + 0x75, 0x9b, 0x68, 0x08, 0xff, 0xcc, 0x84, 0x7a, 0xc7, 0x8d, 0xd8, 0x28, 0x66, 0x4e, 0xd7, 0x19, + 0x4b, 0x42, 0xe6, 0xc7, 0x6e, 0x7c, 0xa9, 0x43, 0xbc, 0x86, 0xd2, 0xfc, 0x6e, 0xce, 0x57, 0xce, + 0xca, 0x2e, 0x45, 0x59, 0xf0, 0x2b, 0x00, 0xbd, 0x07, 0xa0, 0xca, 0x25, 0x59, 0xf4, 0x97, 0xae, + 0x2f, 0xfa, 0xab, 0x92, 0x54, 0x7c, 0x0a, 0x25, 0x29, 0x3e, 0x57, 0xa5, 0x00, 0x4b, 0x76, 0x04, + 0x53, 0xe1, 0xce, 0xb2, 0x68, 0x38, 0x61, 0x9e, 0x74, 0x57, 0x59, 0x34, 0x9c, 0x30, 0x2f, 0xad, + 0xf1, 0x2a, 0xea, 0x48, 0xe2, 0x1b, 0xdd, 0x07, 0x33, 0x08, 0xe5, 0x1d, 0x73, 0x42, 0xf3, 0x17, + 0xdc, 0x38, 0x08, 0x89, 0x19, 0x84, 0x08, 0x83, 0xa5, 0xaa, 0xda, 0x56, 0x55, 0xba, 0x39, 0xc8, + 0xf0, 0x20, 0xcb, 0x2a, 0xa2, 0x57, 0xf0, 0x1d, 0x30, 0x0f, 0x42, 0x54, 0x81, 0x62, 0xbf, 0x3b, + 0x68, 0x16, 0xc4, 0x47, 0xa7, 0xbb, 0xdb, 0x34, 0xf0, 0x5f, 0x0d, 0xa8, 0xee, 0x4d, 0x63, 0x2a, + 0x7c, 0x8c, 0x5f, 0x67, 0xdc, 0xe7, 0xc1, 0xe6, 0x31, 0x8d, 0x64, 0x52, 0x35, 0x55, 0xe0, 0x90, + 0xf0, 0x80, 0xa3, 0xd7, 0xa1, 0xcc, 0x9c, 0x31, 0x4b, 0xde, 0xfe, 0xed, 0x65, 0x67, 0x25, 0x8a, + 0x04, 0xbd, 0x09, 0x16, 0x1f, 0x9d, 0xb1, 0x09, 0x6d, 0x95, 0xe6, 0x89, 0xfb, 0x12, 0xab, 0xf2, + 0x20, 0xd1, 0x34, 0xb2, 0x39, 0x89, 0x82, 0x50, 0x56, 0xe7, 0x65, 0xdd, 0x9c, 0x44, 0x41, 0x28, + 0x6a, 0xf3, 0x4d, 0x78, 0xce, 0x1d, 0xfb, 0x41, 0xc4, 0x86, 0xae, 0xef, 0xb0, 0xd9, 0x70, 0x14, + 0xf8, 0xa7, 0x9e, 0x3b, 0x8a, 0xa5, 0x5e, 0x6d, 0xf2, 0xac, 0x5a, 0xec, 0x89, 0xb5, 0x6d, 0xbd, + 0x84, 0xef, 0x43, 0xf5, 0x09, 0xbb, 0x94, 0x45, 0x2e, 0x47, 0x6d, 0x30, 0xcf, 0x2f, 0x74, 0xc2, + 0x84, 0xe4, 0x14, 0x4f, 0x8e, 0x89, 0x79, 0x7e, 0x81, 0xff, 0x60, 0x82, 0xfd, 0x8f, 0x65, 0x92, + 0xb7, 0xa1, 0x3a, 0x49, 0xd4, 0xa8, 0x5f, 0x5d, 0x5a, 0x55, 0xa7, 0xfa, 0x25, 0x19, 0x0d, 0xea, + 0xc2, 0x9d, 0xdc, 0xae, 0xf1, 0xcc, 0x17, 0x37, 0x10, 0xc1, 0x5c, 0xa7, 0x98, 0x2b, 0x31, 0xfe, + 0x76, 0x46, 0x9e, 0x61, 0xf5, 0x2d, 0x4a, 0xcb, 0x6e, 0x91, 0x45, 0x81, 0xf2, 0x8d, 0xa2, 0xc0, + 0x7d, 0xb8, 0x35, 0xf2, 0x18, 0xf5, 0x87, 0xd9, 0x23, 0x56, 0x3e, 0xba, 0x22, 0xd1, 0x87, 0xe9, + 0x4b, 0xd6, 0x51, 0xad, 0x92, 0xe5, 0xe9, 0xd7, 0xa0, 0xec, 0x30, 0x2f, 0xa6, 0x8b, 0x0d, 0xdb, + 0x41, 0x44, 0x47, 0x1e, 0xeb, 0x88, 0x25, 0xa2, 0x28, 0xf0, 0xcb, 0x50, 0x7c, 0x72, 0xdc, 0xbf, + 0x56, 0xfb, 0xdf, 0x01, 0xf3, 0xc9, 0x71, 0x3e, 0x76, 0xd6, 0x95, 0x14, 0xdd, 0x92, 0x9b, 0x59, + 0x4b, 0xde, 0x06, 0x7b, 0xca, 0x59, 0xb4, 0xc7, 0x62, 0xaa, 0x1f, 0x6e, 0x0a, 0x8b, 0x44, 0x27, + 0x7a, 0x4a, 0x37, 0xf0, 0x75, 0x52, 0x49, 0x40, 0xfc, 0xb7, 0x22, 0x54, 0xf4, 0xe3, 0x15, 0x7b, + 0x4e, 0xd3, 0x1a, 0x50, 0x7c, 0x66, 0x91, 0xc0, 0xcc, 0x47, 0x82, 0x7c, 0xf3, 0x5f, 0xbc, 0x59, + 0xf3, 0x8f, 0xbe, 0x01, 0xf5, 0x50, 0xad, 0xe5, 0xe3, 0xc7, 0x0b, 0x8b, 0x7c, 0xfa, 0x57, 0xf2, + 0xd6, 0xc2, 0x0c, 0x10, 0xde, 0x2f, 0x1b, 0xa0, 0x98, 0x8e, 0xa5, 0x09, 0xeb, 0xa4, 0x22, 0xe0, + 0x01, 0x1d, 0x3f, 0x25, 0x8a, 0xdc, 0x20, 0x10, 0x88, 0x9a, 0x37, 0x08, 0x5b, 0x75, 0xe9, 0xc2, + 0x22, 0x78, 0xe4, 0xdf, 0x75, 0x63, 0xfe, 0x5d, 0xbf, 0x00, 0xd5, 0x51, 0x30, 0x99, 0xb8, 0x72, + 0x6d, 0x45, 0xa5, 0x5e, 0x85, 0x18, 0x70, 0xfc, 0x25, 0x54, 0xf4, 0x85, 0x51, 0x0d, 0x2a, 0x9d, + 0xee, 0xce, 0xd6, 0xd1, 0xae, 0x88, 0x2c, 0x00, 0xd6, 0x47, 0xbd, 0xfd, 0x2d, 0xf2, 0x79, 0xd3, + 0x10, 0x51, 0xa6, 0xb7, 0x3f, 0x68, 0x9a, 0xa8, 0x0a, 0xe5, 0x9d, 0xdd, 0x83, 0xad, 0x41, 0xb3, + 0x88, 0x6c, 0x28, 0x7d, 0x74, 0x70, 0xb0, 0xdb, 0x2c, 0xa1, 0x3a, 0xd8, 0x9d, 0xad, 0x41, 0x77, + 0xd0, 0xdb, 0xeb, 0x36, 0xcb, 0x82, 0xf6, 0x71, 0xf7, 0xa0, 0x69, 0x89, 0x8f, 0xa3, 0x5e, 0xa7, + 0x59, 0x11, 0xeb, 0x87, 0x5b, 0xfd, 0xfe, 0x67, 0x07, 0xa4, 0xd3, 0xb4, 0xc5, 0xbe, 0xfd, 0x01, + 0xe9, 0xed, 0x3f, 0x6e, 0x56, 0xf1, 0x03, 0xa8, 0xe5, 0x94, 0x26, 0x38, 0x48, 0x77, 0xa7, 0x59, + 0x10, 0x62, 0x8e, 0xb7, 0x76, 0x8f, 0xba, 0x4d, 0x03, 0xad, 0x00, 0xc8, 0xcf, 0xe1, 0xee, 0xd6, + 0xfe, 0xe3, 0xa6, 0x89, 0xbf, 0x6b, 0xa4, 0x3c, 0xb2, 0xa9, 0x7e, 0x03, 0x6c, 0xad, 0xea, 0xa4, + 0x68, 0xbe, 0xb5, 0x60, 0x17, 0x92, 0x12, 0x08, 0x37, 0x1b, 0x9d, 0xb1, 0xd1, 0x39, 0x9f, 0x4e, + 0xb4, 0x57, 0xa4, 0xb0, 0xea, 0x8d, 0x85, 0x4e, 0x74, 0xda, 0xd4, 0x50, 0x3a, 0x60, 0x2a, 0x49, + 0x7a, 0x35, 0x60, 0x7a, 0x08, 0x90, 0x8d, 0x30, 0x96, 0x94, 0xbb, 0xb7, 0xa1, 0x4c, 0x3d, 0x97, + 0x72, 0x9d, 0x99, 0x14, 0x80, 0x09, 0xd4, 0x72, 0x83, 0x0f, 0x61, 0x30, 0xea, 0x79, 0xc3, 0x73, + 0x76, 0xc9, 0x25, 0xaf, 0x4d, 0x2a, 0xd4, 0xf3, 0x9e, 0xb0, 0x4b, 0x8e, 0xd6, 0xa1, 0xac, 0xe6, + 0x26, 0xe6, 0x92, 0x0e, 0x5b, 0xb2, 0x13, 0x45, 0x80, 0xdf, 0x04, 0x4b, 0xb5, 0xdd, 0x39, 0x9f, + 0x31, 0x9e, 0x9a, 0x3c, 0x3e, 0xd4, 0xe7, 0x96, 0x4d, 0x3a, 0x7a, 0x5b, 0xcf, 0x68, 0xb8, 0x9a, + 0x0c, 0x19, 0xf3, 0xa5, 0x95, 0x22, 0xd4, 0xe3, 0x19, 0xc9, 0x80, 0x3b, 0x60, 0x5f, 0x3b, 0x01, + 0xd3, 0x8a, 0x30, 0x33, 0x45, 0x2c, 0x99, 0x89, 0xe1, 0x08, 0x20, 0x9b, 0xe3, 0x68, 0x37, 0x56, + 0xbb, 0x08, 0x37, 0xde, 0x10, 0x26, 0x72, 0x3d, 0x27, 0x62, 0xfe, 0x95, 0xdb, 0x67, 0xd3, 0x9f, + 0x94, 0x06, 0xbd, 0x02, 0x25, 0x39, 0xae, 0x52, 0xc1, 0x36, 0x9d, 0x2a, 0xa4, 0xb3, 0x2a, 0xb9, + 0x8a, 0x4f, 0xa0, 0xa1, 0xf2, 0x12, 0x61, 0x5f, 0x4c, 0x19, 0xbf, 0xb6, 0xfa, 0x59, 0x05, 0x48, + 0x03, 0x67, 0x32, 0x80, 0xcb, 0x61, 0x84, 0xa3, 0x9c, 0xba, 0xcc, 0x73, 0x92, 0x5b, 0x69, 0x08, + 0xbf, 0x0f, 0xf5, 0x44, 0x86, 0xec, 0xaf, 0xef, 0xa7, 0x19, 0x32, 0xf1, 0x4b, 0x61, 0x10, 0x45, + 0xb2, 0x1f, 0x38, 0x69, 0x72, 0xc4, 0x7f, 0x32, 0x13, 0x4e, 0xdd, 0x3d, 0xce, 0xd5, 0x5f, 0xc6, + 0x62, 0xfd, 0x35, 0x5f, 0xcb, 0x98, 0x37, 0xae, 0x65, 0xfe, 0x1f, 0xaa, 0x8e, 0x4c, 0xe4, 0xee, + 0x45, 0x12, 0xfa, 0x56, 0x97, 0x25, 0x6d, 0x9d, 0xee, 0xdd, 0x0b, 0x46, 0x32, 0x06, 0x71, 0xa6, + 0x38, 0x38, 0x67, 0xbe, 0xfb, 0xa5, 0x6c, 0x93, 0xc5, 0xc5, 0x33, 0x44, 0x36, 0xc9, 0x50, 0xc9, + 0x5d, 0x4f, 0x32, 0x92, 0x29, 0x8e, 0x95, 0x9b, 0xe2, 0xdc, 0x01, 0x6b, 0x1a, 0x72, 0x16, 0xc5, + 0x49, 0xd1, 0xa7, 0xa0, 0xb4, 0x70, 0xaa, 0x6a, 0x5a, 0xea, 0x8f, 0xf1, 0xff, 0x42, 0x35, 0x3d, + 0x8b, 0x88, 0x37, 0xfb, 0x07, 0xfb, 0x5d, 0x15, 0x1d, 0x7a, 0xfb, 0x9d, 0xee, 0xb7, 0x9a, 0x86, + 0x88, 0x58, 0xa4, 0x7b, 0xdc, 0x25, 0xfd, 0x6e, 0xd3, 0x14, 0x91, 0xa5, 0xd3, 0xdd, 0xed, 0x0e, + 0xba, 0xcd, 0xe2, 0x27, 0x25, 0xbb, 0xd2, 0xb4, 0x89, 0xcd, 0x66, 0xa1, 0xe7, 0x8e, 0xdc, 0x18, + 0x7f, 0x0e, 0xf6, 0x1e, 0x0d, 0xaf, 0x14, 0xf3, 0x59, 0x42, 0x9a, 0xea, 0x51, 0x81, 0x4e, 0x1e, + 0xaf, 0x41, 0x45, 0x47, 0x8d, 0x34, 0x8d, 0x2f, 0x44, 0x95, 0x64, 0x1d, 0xff, 0xd4, 0x80, 0xdb, + 0x7b, 0xc1, 0x05, 0x4b, 0xf3, 0xea, 0x21, 0xbd, 0xf4, 0x02, 0xea, 0x7c, 0x8d, 0x19, 0x5f, 0x85, + 0x5b, 0x3c, 0x98, 0x46, 0x23, 0x36, 0x5c, 0x18, 0x55, 0x34, 0x14, 0xfa, 0xb1, 0x76, 0x47, 0x2c, + 0xaa, 0x16, 0x1e, 0x67, 0x54, 0x45, 0x49, 0x55, 0x13, 0xc8, 0x84, 0x26, 0x2d, 0x10, 0x4a, 0x37, + 0x29, 0x10, 0xf0, 0x6f, 0x0c, 0x68, 0x74, 0x67, 0x61, 0x10, 0xc5, 0xc9, 0x51, 0x9f, 0x13, 0xa5, + 0xf8, 0x17, 0xc9, 0x63, 0x28, 0x91, 0x72, 0xc4, 0xbe, 0xe8, 0x5d, 0x3b, 0x47, 0x79, 0x08, 0x96, + 0xd8, 0x6c, 0xca, 0xb5, 0x2b, 0xbd, 0x98, 0xc8, 0x9c, 0xdb, 0x78, 0xa3, 0x2f, 0x69, 0x88, 0xa6, + 0xcd, 0xcf, 0xb0, 0x4a, 0xf9, 0x19, 0x16, 0x7e, 0x04, 0x96, 0x22, 0xcd, 0xd9, 0xb9, 0x06, 0x95, + 0xfe, 0xd1, 0xf6, 0x76, 0xb7, 0xdf, 0x6f, 0x1a, 0xa8, 0x01, 0xd5, 0xce, 0xd1, 0xe1, 0x6e, 0x6f, + 0x7b, 0x6b, 0xa0, 0x6d, 0xbd, 0xb3, 0xd5, 0xdb, 0xed, 0x76, 0x9a, 0x45, 0xfc, 0x0b, 0x03, 0x6a, + 0xb9, 0x02, 0x05, 0x3d, 0x12, 0x9d, 0xb1, 0x88, 0xdd, 0x49, 0x28, 0x5c, 0x5b, 0x52, 0xc6, 0x6c, + 0x6c, 0x2b, 0x12, 0x3d, 0x16, 0xd1, 0x0c, 0xc2, 0x3d, 0xe9, 0x49, 0x10, 0xe9, 0x59, 0x4a, 0x89, + 0x68, 0xe8, 0x6b, 0x3b, 0xab, 0xf6, 0x23, 0xa8, 0xe7, 0x77, 0x5c, 0xd2, 0x31, 0xce, 0xd5, 0x23, + 0xa5, 0x7c, 0x87, 0xf8, 0x12, 0x34, 0x44, 0x1b, 0xec, 0x4e, 0x18, 0x8f, 0xe9, 0x24, 0x94, 0xb9, + 0x5d, 0x1f, 0xbe, 0x44, 0xcc, 0x98, 0xe3, 0x57, 0xa1, 0x7e, 0xc8, 0x58, 0x44, 0x18, 0x0f, 0x03, + 0x9f, 0xcb, 0x86, 0x48, 0x2b, 0x5f, 0x25, 0x0e, 0x0d, 0xe1, 0xbb, 0x50, 0xdc, 0x9f, 0x4e, 0xf2, + 0x7f, 0x79, 0x94, 0x64, 0x7d, 0x85, 0x77, 0xa0, 0xde, 0xd7, 0x93, 0x33, 0x59, 0x53, 0x89, 0x8a, + 0xc0, 0x73, 0x99, 0x2f, 0x2b, 0x02, 0x43, 0x57, 0x04, 0x12, 0x31, 0xe0, 0xd7, 0x58, 0x7d, 0xf3, + 0x97, 0x06, 0x94, 0x44, 0x53, 0x2e, 0xc2, 0x6e, 0x77, 0x74, 0x16, 0x20, 0x35, 0x05, 0xd4, 0xd6, + 0x6e, 0xcf, 0x41, 0xb8, 0x80, 0xde, 0x50, 0xc3, 0xc0, 0x64, 0x82, 0x7a, 0x3d, 0xf1, 0x26, 0xd4, + 0x3e, 0x09, 0x5c, 0x7f, 0x5b, 0x8d, 0xc7, 0x50, 0x5a, 0x7b, 0xe6, 0xc6, 0x89, 0x57, 0x78, 0xde, + 0x05, 0xab, 0xc7, 0x85, 0x6a, 0x96, 0x93, 0xa7, 0x4d, 0x49, 0x5e, 0x7b, 0xb8, 0xb0, 0xf9, 0xe3, + 0x22, 0x94, 0x44, 0x77, 0x8f, 0x1e, 0x42, 0x45, 0xb7, 0xe6, 0x68, 0xa1, 0x05, 0x6f, 0xa7, 0x8f, + 0x68, 0xa1, 0x77, 0xc7, 0x05, 0xf4, 0x1e, 0x58, 0x3a, 0x52, 0xcf, 0xcf, 0x0f, 0xda, 0x4f, 0x7b, + 0x78, 0xb8, 0xb0, 0x6e, 0xfc, 0x8f, 0x81, 0xde, 0x06, 0x4b, 0x79, 0xe0, 0x82, 0x26, 0x96, 0x95, + 0xd9, 0xb8, 0x20, 0x19, 0x6a, 0xfd, 0xb3, 0x60, 0xea, 0x39, 0x7d, 0x16, 0x5d, 0x30, 0xb4, 0x30, + 0xad, 0x6a, 0x2f, 0xc0, 0xb8, 0x80, 0xde, 0x02, 0xd8, 0xe2, 0xdc, 0x1d, 0xfb, 0x47, 0xae, 0xc3, + 0x51, 0x2d, 0x59, 0xdf, 0x9f, 0x4e, 0xda, 0x4d, 0x29, 0x52, 0xad, 0x8a, 0x4e, 0x87, 0x2b, 0xf2, + 0x9c, 0xd7, 0x7d, 0x2d, 0xf9, 0x3b, 0xd0, 0x50, 0x3e, 0x7e, 0x10, 0x6d, 0x89, 0x67, 0x81, 0x16, + 0x7b, 0x9b, 0xf6, 0x22, 0x02, 0x17, 0xd0, 0x23, 0xb0, 0x07, 0xd1, 0xa5, 0xa2, 0x7f, 0x2e, 0x3d, + 0x70, 0xde, 0xdd, 0xdb, 0xcb, 0xd1, 0xb8, 0xb0, 0xf9, 0x97, 0x22, 0x58, 0x9f, 0x05, 0xd1, 0x39, + 0x8b, 0xd0, 0x06, 0x58, 0xb2, 0xfd, 0x62, 0xe8, 0x6a, 0x3b, 0xb6, 0x4c, 0xec, 0x9b, 0x50, 0x95, + 0x4a, 0x1b, 0x50, 0x7e, 0x9e, 0x99, 0x49, 0xfe, 0xe3, 0x96, 0xe9, 0x4d, 0x65, 0x6a, 0x5c, 0x40, + 0xdf, 0x84, 0x3b, 0x69, 0xf8, 0xde, 0xf2, 0x1d, 0x95, 0x0e, 0x3b, 0x34, 0xa6, 0x28, 0xeb, 0x6b, + 0x73, 0xef, 0xa7, 0x5d, 0xcb, 0x3a, 0x9d, 0xbe, 0xb4, 0xd4, 0x03, 0x28, 0xf5, 0xc5, 0x0d, 0xb3, + 0xff, 0xcb, 0xb2, 0x7f, 0x0e, 0xda, 0x28, 0x8f, 0x4c, 0x65, 0xbe, 0x0f, 0x96, 0x92, 0x93, 0xa9, + 0x65, 0xae, 0x46, 0x69, 0xdf, 0x5e, 0x44, 0x6b, 0xc6, 0xfb, 0x60, 0xef, 0xb9, 0xbe, 0x1a, 0x9c, + 0xcd, 0x3b, 0x52, 0xde, 0x82, 0xb8, 0x80, 0x3e, 0x00, 0x4b, 0x45, 0xe3, 0x4c, 0xc2, 0x5c, 0x74, + 0x6e, 0x2f, 0x47, 0xe3, 0x02, 0x7a, 0x00, 0x4d, 0xc2, 0x46, 0xcc, 0xcd, 0x65, 0x35, 0x94, 0xbf, + 0xf3, 0xe2, 0x43, 0x5c, 0x37, 0xd0, 0x87, 0xd0, 0x98, 0xcb, 0x82, 0x28, 0xcd, 0x08, 0xcb, 0x92, + 0xe3, 0xe2, 0x06, 0x1f, 0x35, 0x7f, 0xfd, 0xd5, 0xaa, 0xf1, 0xbb, 0xaf, 0x56, 0x8d, 0x3f, 0x7e, + 0xb5, 0x6a, 0xfc, 0xf0, 0xcf, 0xab, 0x85, 0x13, 0x4b, 0xfe, 0xd1, 0xfb, 0xce, 0xdf, 0x03, 0x00, + 0x00, 0xff, 0xff, 0x32, 0x3d, 0x16, 0xb3, 0x0d, 0x1e, 0x00, 0x00, } diff --git a/protos/internal.proto b/protos/internal.proto index 5a9b43c4ccc..148c224ab23 100644 --- a/protos/internal.proto +++ b/protos/internal.proto @@ -196,12 +196,14 @@ message KeyValues { message Proposal { uint32 deprecated_id = 1; // delete this field in later versions. Its for backward compatibility. + api.TxnContext deprecated_txn_context = 3; + Mutations mutations = 2; - api.TxnContext txn_context = 3; repeated KV kv = 4; MembershipState state = 5; string clean_predicate = 6; // Delete the predicate which was moved to other group. string key = 7; + OracleDelta delta = 8; } message KVS { diff --git a/worker/draft.go b/worker/draft.go index ba02107ab66..b9297642105 100644 --- a/worker/draft.go +++ b/worker/draft.go @@ -315,8 +315,10 @@ func (n *node) processEdge(ridx uint64, pkey string, edge *intern.DirectedEdge) // of name and delete it from "janardhan"'s index. If we don't // wait for commit information then mutation won't see the value - // TODO: We should propose Oracle via Raft, and not wait here. - posting.Oracle().WaitForTs(context.Background(), txn.StartTs) + // We used to Oracle().WaitForTs here. + // TODO: Need to ensure that keys which hold values can only keep one pending txn at a + // time. Otherwise, their index generated would be wrong. + if err := runMutation(ctx, edge, txn); err != nil { if tr, ok := trace.FromContext(ctx); ok { tr.LazyPrintf("process mutation: %v", err) @@ -523,9 +525,20 @@ func (n *node) applyCommitted(proposal *intern.Proposal, index uint64) error { } else if len(proposal.CleanPredicate) > 0 { return n.deletePredicate(proposal.Key, proposal.CleanPredicate) - } else if proposal.TxnContext != nil { + } else if proposal.DeprecatedTxnContext != nil { n.elog.Printf("Applying txncontext for key: %s", proposal.Key) - return n.commitOrAbort(proposal.Key, proposal.TxnContext) + delta := &intern.OracleDelta{} + tctx := proposal.DeprecatedTxnContext + if tctx.CommitTs == 0 { + delta.Aborts = append(delta.Aborts, tctx.StartTs) + } else { + delta.Commits = make(map[uint64]uint64) + delta.Commits[tctx.StartTs] = tctx.CommitTs + } + return n.commitOrAbort(proposal.Key, delta) + } else if proposal.Delta != nil { + n.elog.Printf("Applying Oracle Delta for key: %s", proposal.Key) + return n.commitOrAbort(proposal.Key, proposal.Delta) } else { x.Fatalf("Unknown proposal") } @@ -545,17 +558,37 @@ func (n *node) processApplyCh() { } } -func (n *node) commitOrAbort(pkey string, tctx *api.TxnContext) error { +func (n *node) commitOrAbort(pkey string, delta *intern.OracleDelta) error { ctx, _ := n.props.CtxAndTxn(pkey) - _, err := commitOrAbort(ctx, tctx) - if tr, ok := trace.FromContext(ctx); ok { - tr.LazyPrintf("Status of commitOrAbort %+v %v\n", tctx, err) + + applyTxnStatus := func(startTs, commitTs uint64) { + var err error + for i := 0; i < 3; i++ { + err = commitOrAbort(ctx, startTs, commitTs) + if err == nil || err == posting.ErrInvalidTxn { + break + } + x.Printf("Error while applying txn status (%d -> %d): %v", startTs, commitTs, err) + } + // TODO: Even after multiple tries, if we're unable to apply the status of a transaction, + // what should we do? Maybe do a printf, and let them know that there might be a disk issue. + posting.Txns().Done(startTs) + posting.Oracle().Done(startTs) + if tr, ok := trace.FromContext(ctx); ok { + tr.LazyPrintf("Status of commitOrAbort startTs %d: %v\n", startTs, err) + } + } + + for startTs, commitTs := range delta.GetCommits() { + applyTxnStatus(startTs, commitTs) } - if err == nil { - posting.Txns().Done(tctx.StartTs) - posting.Oracle().Done(tctx.StartTs) + for _, startTs := range delta.GetAborts() { + applyTxnStatus(startTs, 0) } - return err + // TODO: Use MaxPending to track the txn watermark. That's the only thing we need really. + // delta.GetMaxPending + posting.Oracle().ProcessOracleDelta(delta) + return nil } func (n *node) deletePredicate(pkey string, predicate string) error { diff --git a/worker/groups.go b/worker/groups.go index be2798f6ba4..cb9c8fdd0e2 100644 --- a/worker/groups.go +++ b/worker/groups.go @@ -16,6 +16,7 @@ import ( "google.golang.org/grpc" "golang.org/x/net/context" + "golang.org/x/net/trace" "github.com/dgraph-io/badger" "github.com/dgraph-io/dgo/protos/api" @@ -668,79 +669,133 @@ func (g *groupi) sendMembership(tablets map[string]*intern.Tablet, return stream.Send(group) } -func (g *groupi) proposeDelta(oracleDelta *intern.OracleDelta) { - if !g.Node.AmLeader() { - return - } - - // Only the leader of a group proposes the commit proposal for a group after getting delta from - // Zero. - for startTs, commitTs := range oracleDelta.Commits { - // The leader might not have yet applied the mutation and hence may not have the txn in the - // map. Its ok we can just continue, processOracleDeltaStream checks the oracle map every - // minute and calls proposeDelta. - if posting.Txns().Get(startTs) == nil { - // Don't mark oracle as done here as then it would be deleted the entry from map and it - // won't be proposed to the group. This could eventually block snapshots from happening - // in a replicated cluster. - continue - } - tctx := &api.TxnContext{StartTs: startTs, CommitTs: commitTs} - go g.Node.proposeAndWait(context.Background(), &intern.Proposal{TxnContext: tctx}) - } - for _, startTs := range oracleDelta.Aborts { - if posting.Txns().Get(startTs) == nil { - continue - } - tctx := &api.TxnContext{StartTs: startTs} - go g.Node.proposeAndWait(context.Background(), &intern.Proposal{TxnContext: tctx}) - } -} - // processOracleDeltaStream is used to process oracle delta stream from Zero. // Zero sends information about aborted/committed transactions and maxPending. func (g *groupi) processOracleDeltaStream() { - go func() { - // TODO (pawan) - What is this for? Comment says this is required when there is no leader - // but proposeDelta returns if the current node is not leader. - - // In the event where there in no leader for a group, commit/abort won't get proposed. - // So periodically check oracle and propose - // Ticker time should be long enough so that same startTs - // doesn't get proposed again and again. - ticker := time.NewTicker(time.Minute) - for range ticker.C { - g.proposeDelta(posting.Oracle().CurrentState()) + blockingReceiveAndPropose := func() { + elog := trace.NewEventLog("Dgraph", "ProcessOracleStream") + defer elog.Finish() + elog.Printf("Leader idx=%d of group=%d is connecting to Zero for txn updates\n", + g.Node.Id, g.groupId()) + + pl := g.Leader(0) + if pl == nil { + x.Printf("WARNING: We don't have address of any dgraphzero leader.") + elog.Errorf("Dgraph zero leader address unknown") + time.Sleep(time.Second) + return } - }() -START: - pl := g.Leader(0) - // We should always have some connection to dgraphzero. - if pl == nil { - x.Printf("WARNING: We don't have address of any dgraphzero leader.") - time.Sleep(time.Second) - goto START - } + // The following code creates a stream. Then runs a goroutine to pick up events from the + // stream and pushes them to a channel. The main loop loops over the channel, doing smart + // batching. Once a batch is created, it gets proposed. Thus, we can reduce the number of + // times proposals happen, which is a great optimization to have (and a common one in our + // code base). + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + c := intern.NewZeroClient(pl.Get()) + // The first entry send by Zero contains the entire state of transactions. Zero periodically + // confirms receipt from the group, and truncates its state. This 2-way acknowledgement is a + // safe way to get the status of all the transactions. + stream, err := c.Oracle(ctx, &api.Payload{}) + if err != nil { + x.Printf("Error while calling Oracle %v\n", err) + elog.Errorf("Error while calling Oracle %v", err) + cancel() + time.Sleep(time.Second) + return + } - c := intern.NewZeroClient(pl.Get()) - stream, err := c.Oracle(context.Background(), &api.Payload{}) - if err != nil { - x.Printf("Error while calling Oracle %v\n", err) - time.Sleep(time.Second) - goto START + deltaCh := make(chan *intern.OracleDelta, 100) + go func() { + // This would exit when either a Recv() returns error. Or, cancel() is called by + // something outside of this goroutine. + defer stream.CloseSend() + defer close(deltaCh) + + for { + delta, err := stream.Recv() + if err != nil || delta == nil { + x.Printf("Error in oracle delta stream. Error: %v", err) + return + } + + select { + case deltaCh <- delta: + case <-ctx.Done(): + return + } + } + }() + + for { + var delta *intern.OracleDelta + var batch int + select { + case delta = <-deltaCh: + if delta == nil { + return + } + batch++ + case <-ctx.Done(): + return + } + + SLURP: + for { + select { + case more := <-deltaCh: + if more == nil { + return + } + batch++ + if delta.Commits == nil { + delta.Commits = make(map[uint64]uint64) + } + // Merge more with delta. + for start, commit := range more.GetCommits() { + delta.Commits[start] = commit + } + delta.Aborts = append(delta.Aborts, more.Aborts...) + if delta.MaxPending < more.MaxPending { + delta.MaxPending = more.MaxPending + } + default: + break SLURP + } + } + + // Only the leader needs to propose the oracleDelta retrieved from Zero. + // The leader and the followers would not directly apply or use the + // oracleDelta streaming in from Zero. They would wait for the proposal to + // go through and be applied via node.Run. This saves us from many edge + // cases around network partitions and race conditions between prewrites and + // commits, etc. + if !g.Node.AmLeader() { + elog.Errorf("No longer the leader of group %d. Exiting", g.groupId()) + return + } + // Block forever trying to propose this. + elog.Printf("Batched %d updates. Proposing Delta of size: %d.", batch, delta.Size()) + g.Node.proposeAndWait(context.Background(), &intern.Proposal{Delta: delta}) + } } + ticker := time.NewTicker(time.Second) + defer ticker.Stop() +START: for { - oracleDelta, err := stream.Recv() - if err != nil || oracleDelta == nil { - x.Printf("Error in oracle delta stream. Error: %v", err) - break + select { + case <-g.Node.stop: + return + case <-ticker.C: + // Only the leader needs to connect to Zero and get transaction + // updates. + if g.Node.AmLeader() { + break START + } } - posting.Oracle().ProcessOracleDelta(oracleDelta) - // Do Immediately so that index keys are written. - g.proposeDelta(oracleDelta) } - time.Sleep(time.Second) + blockingReceiveAndPropose() goto START } diff --git a/worker/mutation.go b/worker/mutation.go index 8fa6056bbaf..99ef6d2ba8b 100644 --- a/worker/mutation.go +++ b/worker/mutation.go @@ -40,9 +40,6 @@ func deletePredicateEdge(edge *intern.DirectedEdge) bool { // runMutation goes through all the edges and applies them. func runMutation(ctx context.Context, edge *intern.DirectedEdge, txn *posting.Txn) error { - if tr, ok := trace.FromContext(ctx); ok { - tr.LazyPrintf("In run mutation") - } if !groups().ServesTabletRW(edge.Attr) { // Don't assert, can happen during replay of raft logs if server crashes immediately // after predicate move and before snapshot. @@ -495,20 +492,20 @@ func populateMutationMap(src *intern.Mutations) map[uint32]*intern.Mutations { return mm } -func commitOrAbort(ctx context.Context, tc *api.TxnContext) (*api.Payload, error) { - txn := posting.Txns().Get(tc.StartTs) +func commitOrAbort(ctx context.Context, startTs, commitTs uint64) error { + txn := posting.Txns().Get(startTs) if txn == nil { - return &api.Payload{}, posting.ErrInvalidTxn + return posting.ErrInvalidTxn } // Ensures that we wait till prewrite is applied idx := txn.LastIndex() groups().Node.Applied.WaitForMark(ctx, idx) - if tc.CommitTs == 0 { + if commitTs == 0 { err := txn.AbortMutations(ctx) - return &api.Payload{}, err + return err } - err := txn.CommitMutations(ctx, tc.CommitTs) - return &api.Payload{}, err + err := txn.CommitMutations(ctx, commitTs) + return err } type res struct { @@ -616,7 +613,7 @@ func tryAbortTransactions(startTimestamps []uint64) { for i, startTs := range startTimestamps { tctx := &api.TxnContext{StartTs: startTs, CommitTs: commitTimestamps[i]} - _, err := commitOrAbort(context.Background(), tctx) + err := commitOrAbort(context.Background(), tctx.StartTs, tctx.CommitTs) // Transaction could already have been aborted in which case it would be deleted from the // transactions map and we should just continue. // TODO - Make sure all other errors are transient, we don't want to be stuck in an infinite @@ -624,7 +621,7 @@ func tryAbortTransactions(startTimestamps []uint64) { for err != nil && err != posting.ErrInvalidTxn { x.Printf("Error while locally aborting txns: %v\n", err) // This will fail only due to badger error. - _, err = commitOrAbort(context.Background(), tctx) + err = commitOrAbort(context.Background(), tctx.StartTs, tctx.CommitTs) } } }