Commit 36f18d1b authored by harrylee's avatar harrylee

fix a bug for initbroker

parent 0df097c6
Pipeline #8235 failed with stages
in 0 seconds
...@@ -13,7 +13,7 @@ import ( ...@@ -13,7 +13,7 @@ import (
//BrokerDB ... //BrokerDB ...
type BrokerDB struct { type BrokerDB struct {
api client.QueueProtocolAPI api client.QueueProtocolAPI
db dbm.KV statedb dbm.KV
localdb dbm.KV localdb dbm.KV
txhash []byte txhash []byte
fromaddr string fromaddr string
...@@ -24,7 +24,7 @@ type BrokerDB struct { ...@@ -24,7 +24,7 @@ type BrokerDB struct {
var ( var (
// DefaultManagerAddr 默认管理员地址 // DefaultManagerAddr 默认管理员地址
DefaultManagerAddr = "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv" DefaultManagerAddr = "14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
) )
func newBrokerDB(b *broker, tx *types.Transaction, index int) *BrokerDB { func newBrokerDB(b *broker, tx *types.Transaction, index int) *BrokerDB {
...@@ -55,24 +55,27 @@ func (b *BrokerDB) GetEventKVSet(event *brokertypes.InterchainEvent) (kvset []*t ...@@ -55,24 +55,27 @@ func (b *BrokerDB) GetEventKVSet(event *brokertypes.InterchainEvent) (kvset []*t
//初始化broker //初始化broker
func (b *BrokerDB) initBroker(payload *brokertypes.Init) (*types.Receipt, error) { func (b *BrokerDB) initBroker(payload *brokertypes.Init) (*types.Receipt, error) {
//权限检查且只能初始化一次 //权限检查且只能初始化一次
if b.fromaddr != getManagerAddr(b.api.GetConfig(), b.db, brokerAdmin, DefaultManagerAddr) { if b.fromaddr != getManagerAddr(b.api.GetConfig(), b.statedb, brokerAdmin, DefaultManagerAddr) {
return nil, fmt.Errorf("the addr %s is not admin", b.fromaddr) return nil, fmt.Errorf("the addr %s is not admin", b.fromaddr)
} }
m := make(map[string]uint64)
//初始化map,填充一些默认值,防止序列化后为nil
m["broker"] = 0
meta := &brokertypes.Meta{ meta := &brokertypes.Meta{
Meta: make(map[string]uint64), Meta: m,
XXX_NoUnkeyedLiteral: struct{}{},
XXX_unrecognized: nil,
XXX_sizecache: 0,
} }
var kvsets []*types.KeyValue var kvsets []*types.KeyValue
kvsets = append(kvsets,&types.KeyValue{Key: calOutterMetaKey(), Value: types.Encode(meta)}) kvsets = append(kvsets, &types.KeyValue{Key: calOutterMetaKey(), Value: types.Encode(meta)})
kvsets = append(kvsets,&types.KeyValue{Key: calInnerMetaKey(), Value: types.Encode(meta)}) kvsets = append(kvsets, &types.KeyValue{Key: calInnerMetaKey(), Value: types.Encode(meta)})
kvsets = append(kvsets,&types.KeyValue{Key: calCallBackMetaKey(), Value: types.Encode(meta)}) kvsets = append(kvsets, &types.KeyValue{Key: calCallBackMetaKey(), Value: types.Encode(meta)})
kvsets = append(kvsets,&types.KeyValue{Key: calDstRollBackMetaKey(), Value: types.Encode(meta)}) kvsets = append(kvsets, &types.KeyValue{Key: calDstRollBackMetaKey(), Value: types.Encode(meta)})
receipt := &types.Receipt{Ty: types.ExecOk} receipt := &types.Receipt{Ty: types.ExecOk}
receipt.KV = append(receipt.KV,kvsets...) receipt.KV = append(receipt.KV, kvsets...)
receipt.KV = append(receipt.KV, &types.KeyValue{Key: BxhIDKey(), Value: types.Encode(payload)}) receipt.KV = append(receipt.KV, &types.KeyValue{Key: BxhIDKey(), Value: types.Encode(payload)})
receipt.Ty = brokertypes.TyInitLog receipt.Ty = brokertypes.TyInitLog
for _, v := range receipt.KV {
elog.Error("KV", "key:", string(v.GetKey()), "value", string(v.GetValue()))
}
return receipt, nil return receipt, nil
} }
...@@ -92,9 +95,9 @@ func (b *BrokerDB) updateIndex(payload *brokertypes.UpdateIndex) (*types.Receipt ...@@ -92,9 +95,9 @@ func (b *BrokerDB) updateIndex(payload *brokertypes.UpdateIndex) (*types.Receipt
//FIXME 权限检查 //FIXME 权限检查
receipt := &types.Receipt{Ty: types.ExecOk} receipt := &types.Receipt{Ty: types.ExecOk}
if payload.ReqType == brokertypes.Req_Inner { if payload.ReqType == brokertypes.Req_Inner {
meta, err := getMeta(b.db, calInnerMetaKey()) meta, err := getMeta(b.statedb, calInnerMetaKey())
if err != nil { if err != nil {
return nil,fmt.Errorf("broker not init!") return nil, fmt.Errorf("broker not init!")
} }
idx := meta.Meta[genServicePair(payload.SrcServiceID, payload.DstServiceID)] idx := meta.Meta[genServicePair(payload.SrcServiceID, payload.DstServiceID)]
if payload.SequenceNum != idx+1 { if payload.SequenceNum != idx+1 {
...@@ -106,9 +109,9 @@ func (b *BrokerDB) updateIndex(payload *brokertypes.UpdateIndex) (*types.Receipt ...@@ -106,9 +109,9 @@ func (b *BrokerDB) updateIndex(payload *brokertypes.UpdateIndex) (*types.Receipt
receipt.KV = append(receipt.KV, kvset...) receipt.KV = append(receipt.KV, kvset...)
} else if payload.ReqType == brokertypes.Req_Callback { } else if payload.ReqType == brokertypes.Req_Callback {
meta, err := getMeta(b.db, calCallBackMetaKey()) meta, err := getMeta(b.statedb, calCallBackMetaKey())
if err != nil { if err != nil {
return nil,fmt.Errorf("broker not init!") return nil, fmt.Errorf("broker not init!")
} }
idx := meta.Meta[genServicePair(payload.SrcServiceID, payload.DstServiceID)] idx := meta.Meta[genServicePair(payload.SrcServiceID, payload.DstServiceID)]
if payload.SequenceNum != idx+1 { if payload.SequenceNum != idx+1 {
...@@ -116,13 +119,13 @@ func (b *BrokerDB) updateIndex(payload *brokertypes.UpdateIndex) (*types.Receipt ...@@ -116,13 +119,13 @@ func (b *BrokerDB) updateIndex(payload *brokertypes.UpdateIndex) (*types.Receipt
} }
meta.Meta[genServicePair(payload.SrcServiceID, payload.DstServiceID)] = idx + 1 meta.Meta[genServicePair(payload.SrcServiceID, payload.DstServiceID)] = idx + 1
kvset := b.GetMetaKVSet(payload.ReqType, meta) kvset := b.GetMetaKVSet(payload.ReqType, meta)
kvset = append(kvset, &types.KeyValue{Key: outMsgKey(genServicePair(payload.SrcServiceID, payload.DstServiceID), idx+1), Value: types.Encode(payload.Response)}) // 跨出交易不需要确认是否成功
receipt.KV = append(receipt.KV, kvset...) receipt.KV = append(receipt.KV, kvset...)
} else if payload.ReqType == brokertypes.Req_DstRollback { } else if payload.ReqType == brokertypes.Req_DstRollback {
//todo //todo
meta, err := getMeta(b.db, calDstRollBackMetaKey()) meta, err := getMeta(b.statedb, calDstRollBackMetaKey())
if err != nil { if err != nil {
return nil,fmt.Errorf("broker not init!") return nil, fmt.Errorf("broker not init!")
} }
idx := meta.Meta[genServicePair(payload.SrcServiceID, payload.DstServiceID)] idx := meta.Meta[genServicePair(payload.SrcServiceID, payload.DstServiceID)]
if payload.SequenceNum < idx+1 { if payload.SequenceNum < idx+1 {
...@@ -137,6 +140,7 @@ func (b *BrokerDB) updateIndex(payload *brokertypes.UpdateIndex) (*types.Receipt ...@@ -137,6 +140,7 @@ func (b *BrokerDB) updateIndex(payload *brokertypes.UpdateIndex) (*types.Receipt
receipt.Logs = append(receipt.Logs, receiptlog) receipt.Logs = append(receipt.Logs, receiptlog)
return receipt, nil return receipt, nil
} }
//TODO 重构跨链事件发布 //TODO 重构跨链事件发布
func (b *BrokerDB) emitInterchainEvent(payload *brokertypes.InterchainEvent) (*types.Receipt, error) { func (b *BrokerDB) emitInterchainEvent(payload *brokertypes.InterchainEvent) (*types.Receipt, error) {
//FIXME 权限检查,是否需要设定指定账户拥有跨链的权限 //FIXME 权限检查,是否需要设定指定账户拥有跨链的权限
...@@ -149,9 +153,9 @@ func (b *BrokerDB) emitInterchainEvent(payload *brokertypes.InterchainEvent) (*t ...@@ -149,9 +153,9 @@ func (b *BrokerDB) emitInterchainEvent(payload *brokertypes.InterchainEvent) (*t
if err != nil { if err != nil {
return nil, brokertypes.ErrBrokerStorageTx return nil, brokertypes.ErrBrokerStorageTx
} }
meta, err := getMeta(b.db, calOutterMetaKey()) meta, err := getMeta(b.statedb, calOutterMetaKey())
if err != nil { if err != nil {
return nil,fmt.Errorf("broker not init!") return nil, fmt.Errorf("broker not init!")
} }
currServiceID, err := b.getCurrServiceID() currServiceID, err := b.getCurrServiceID()
if err != nil { if err != nil {
...@@ -164,7 +168,7 @@ func (b *BrokerDB) emitInterchainEvent(payload *brokertypes.InterchainEvent) (*t ...@@ -164,7 +168,7 @@ func (b *BrokerDB) emitInterchainEvent(payload *brokertypes.InterchainEvent) (*t
payload.Index = meta.Meta[genServicePair(currServiceID, payload.DstServiceID)] payload.Index = meta.Meta[genServicePair(currServiceID, payload.DstServiceID)]
receipt.KV = append(receipt.KV, kvset) receipt.KV = append(receipt.KV, kvset)
receipt.KV = append(receipt.KV, b.GetEventKVSet(payload)...) receipt.KV = append(receipt.KV, b.GetEventKVSet(payload)...)
receipt.KV = append(receipt.KV, &types.KeyValue{Key: outMsgKey(genServicePair(payload.SrcServiceID, payload.DstServiceID), payload.Index), Value: types.Encode(payload)})
log := &brokertypes.ReceiptBrokerLog{Value: &brokertypes.ReceiptBrokerLog_EmitInterchainEvent{payload}, Ty: brokertypes.TyEmitInterchainEventAction} log := &brokertypes.ReceiptBrokerLog{Value: &brokertypes.ReceiptBrokerLog_EmitInterchainEvent{payload}, Ty: brokertypes.TyEmitInterchainEventAction}
receiptlog := &types.ReceiptLog{Ty: brokertypes.TyEmitInterchainEventLog, Log: types.Encode(log)} receiptlog := &types.ReceiptLog{Ty: brokertypes.TyEmitInterchainEventLog, Log: types.Encode(log)}
receipt.Logs = append(receipt.Logs, receiptlog) receipt.Logs = append(receipt.Logs, receiptlog)
...@@ -184,7 +188,7 @@ func (b *BrokerDB) getCurrServiceID() (string, error) { ...@@ -184,7 +188,7 @@ func (b *BrokerDB) getCurrServiceID() (string, error) {
func (b *BrokerDB) genFullServiceID(serviceId string) (string, error) { func (b *BrokerDB) genFullServiceID(serviceId string) (string, error) {
//TODO 需要init方法,用于初始化bixhID和appChainID //TODO 需要init方法,用于初始化bixhID和appChainID
data, err := b.db.Get(BxhIDKey()) data, err := b.statedb.Get(BxhIDKey())
if err != nil { if err != nil {
return "", err return "", err
} }
...@@ -238,19 +242,19 @@ func getMeta(statedb dbm.KV, key []byte) (*brokertypes.Meta, error) { ...@@ -238,19 +242,19 @@ func getMeta(statedb dbm.KV, key []byte) (*brokertypes.Meta, error) {
} }
//去状态数据库中查询message //去状态数据库中查询message
func getMessage(statedb dbm.KV, key []byte) (*brokertypes.Response, error) { func getMessage(statedb dbm.KV, key []byte) (*brokertypes.InterchainEvent, error) {
data, err := statedb.Get(key) data, err := statedb.Get(key)
if err != nil { if err != nil {
elog.Error("getMessage", "not found", "key:", key) elog.Error("getMessage", "not found", "key:", key)
return nil, err return nil, err
} }
var resp brokertypes.Response var event brokertypes.InterchainEvent
err = types.Decode(data, &resp) err = types.Decode(data, &event)
if err != nil { if err != nil {
elog.Error("getMessage", "can't decode", "err:", err.Error()) elog.Error("getMessage", "can't decode", "err:", err.Error())
return nil, err return nil, err
} }
return &resp, nil return &event, nil
} }
//监听获取跨出事件列表 //监听获取跨出事件列表
...@@ -287,18 +291,30 @@ func getOutterMeta(statedb dbm.KV) (*brokertypes.Meta, error) { ...@@ -287,18 +291,30 @@ func getOutterMeta(statedb dbm.KV) (*brokertypes.Meta, error) {
func getCallBackMeta(statedb dbm.KV) (*brokertypes.Meta, error) { func getCallBackMeta(statedb dbm.KV) (*brokertypes.Meta, error) {
return getMeta(statedb, calCallBackMetaKey()) return getMeta(statedb, calCallBackMetaKey())
} }
//获取innerMeta //获取innerMeta
func getInnerMeta(statedb dbm.KV) (*brokertypes.Meta, error) { func getInnerMeta(statedb dbm.KV) (*brokertypes.Meta, error) {
return getMeta(statedb, calInnerMetaKey()) return getMeta(statedb, calInnerMetaKey())
} }
//获取message //获取message,用来查询跨入交易执行状态
func getInMessage(statedb dbm.KV, query *brokertypes.QueryInMessage) (*brokertypes.Response, error) { func getInMessage(statedb dbm.KV, query *brokertypes.QueryInMessage) (*brokertypes.Response, error) {
return getMessage(statedb, inMsgKey(query.InServicePair, query.SequenceNum)) data, err := statedb.Get(inMsgKey(query.InServicePair, query.SequenceNum))
if err != nil {
elog.Error("getInMessage", "not found", "key:", inMsgKey(query.InServicePair, query.SequenceNum))
return nil, err
}
var response brokertypes.Response
err = types.Decode(data, &response)
if err != nil {
elog.Error("getInMessage", "can't decode", "err:", err.Error())
return nil, err
}
return &response, nil
} }
//获取message //获取message,实质用来获取跨出事件
func getOutMessage(statedb dbm.KV, query *brokertypes.QueryOutMessage) (*brokertypes.Response, error) { func getOutMessage(statedb dbm.KV, query *brokertypes.QueryOutMessage) (*brokertypes.InterchainEvent, error) {
return getMessage(statedb, outMsgKey(query.InServicePair, query.SequenceNum)) return getMessage(statedb, outMsgKey(query.InServicePair, query.SequenceNum))
} }
......
...@@ -25,7 +25,7 @@ func (b *broker) Query_QueryInMessage(query *brokertypes.QueryInMessage) (*broke ...@@ -25,7 +25,7 @@ func (b *broker) Query_QueryInMessage(query *brokertypes.QueryInMessage) (*broke
} }
//获取outMessage //获取outMessage
func (b *broker) Query_QueryOutMessage(query *brokertypes.QueryOutMessage) (*brokertypes.Response, error) { func (b *broker) Query_QueryOutMessage(query *brokertypes.QueryOutMessage) (*brokertypes.InterchainEvent, error) {
return getOutMessage(b.GetStateDB(), query) return getOutMessage(b.GetStateDB(), query)
} }
......
...@@ -49,8 +49,8 @@ message UpdateIndex { ...@@ -49,8 +49,8 @@ message UpdateIndex {
string srcServiceID = 3; string srcServiceID = 3;
//请求类型 0表示信息流入 1表示信息流出 2表示回滚 //请求类型 0表示信息流入 1表示信息流出 2表示回滚
uint64 reqType =4; uint64 reqType =4;
//响应信息 //跨入交易执行结果更新
Response response = 5; Response response =5;
} }
// 跨链事件 // 跨链事件
message InterchainEvent { message InterchainEvent {
...@@ -133,10 +133,6 @@ message Meta { ...@@ -133,10 +133,6 @@ message Meta {
message Response{ message Response{
// A status code that should follow the HTTP status codes. //状态 0表示开始处理 1表示跨链成功 2表示跨链失败
int32 status = 1; int32 status = 1;
// A message associated with the response code.
string message = 2;
// A payload that can be used to include metadata with this response.
bytes payload = 3;
} }
\ No newline at end of file
...@@ -344,7 +344,7 @@ type UpdateIndex struct { ...@@ -344,7 +344,7 @@ type UpdateIndex struct {
SrcServiceID string `protobuf:"bytes,3,opt,name=srcServiceID,proto3" json:"srcServiceID,omitempty"` SrcServiceID string `protobuf:"bytes,3,opt,name=srcServiceID,proto3" json:"srcServiceID,omitempty"`
//请求类型 0表示信息流入 1表示信息流出 2表示回滚 //请求类型 0表示信息流入 1表示信息流出 2表示回滚
ReqType uint64 `protobuf:"varint,4,opt,name=reqType,proto3" json:"reqType,omitempty"` ReqType uint64 `protobuf:"varint,4,opt,name=reqType,proto3" json:"reqType,omitempty"`
//响应信息 //跨入交易执行结果更新
Response *Response `protobuf:"bytes,5,opt,name=response,proto3" json:"response,omitempty"` Response *Response `protobuf:"bytes,5,opt,name=response,proto3" json:"response,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
...@@ -421,7 +421,7 @@ type InterchainEvent struct { ...@@ -421,7 +421,7 @@ type InterchainEvent struct {
SrcServiceID string `protobuf:"bytes,3,opt,name=srcServiceID,proto3" json:"srcServiceID,omitempty"` SrcServiceID string `protobuf:"bytes,3,opt,name=srcServiceID,proto3" json:"srcServiceID,omitempty"`
//跨链交易类型 0表示storage,1表示coins,2表示token...... //跨链交易类型 0表示storage,1表示coins,2表示token......
Type uint64 `protobuf:"varint,4,opt,name=type,proto3" json:"type,omitempty"` Type uint64 `protobuf:"varint,4,opt,name=type,proto3" json:"type,omitempty"`
//调用方法 //方法集合分别表示 当前,回调,回滚方法 用,号分割 比如: "interchainGet,interchainSet,interchainRollback"
Func string `protobuf:"bytes,5,opt,name=func,proto3" json:"func,omitempty"` Func string `protobuf:"bytes,5,opt,name=func,proto3" json:"func,omitempty"`
//参数列表 //参数列表
Args string `protobuf:"bytes,6,opt,name=args,proto3" json:"args,omitempty"` Args string `protobuf:"bytes,6,opt,name=args,proto3" json:"args,omitempty"`
...@@ -1008,12 +1008,8 @@ func (m *Meta) GetMeta() map[string]uint64 { ...@@ -1008,12 +1008,8 @@ func (m *Meta) GetMeta() map[string]uint64 {
} }
type Response struct { type Response struct {
// A status code that should follow the HTTP status codes. //状态 0表示开始处理 1表示跨链成功 2表示跨链失败
Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"` Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
// A message associated with the response code.
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
// A payload that can be used to include metadata with this response.
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
...@@ -1051,20 +1047,6 @@ func (m *Response) GetStatus() int32 { ...@@ -1051,20 +1047,6 @@ func (m *Response) GetStatus() int32 {
return 0 return 0
} }
func (m *Response) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
func (m *Response) GetPayload() []byte {
if m != nil {
return m.Payload
}
return nil
}
func init() { func init() {
proto.RegisterType((*BrokerAction)(nil), "types.BrokerAction") proto.RegisterType((*BrokerAction)(nil), "types.BrokerAction")
proto.RegisterType((*Init)(nil), "types.Init") proto.RegisterType((*Init)(nil), "types.Init")
...@@ -1092,53 +1074,52 @@ func init() { ...@@ -1092,53 +1074,52 @@ func init() {
} }
var fileDescriptor_f209535e190f2bed = []byte{ var fileDescriptor_f209535e190f2bed = []byte{
// 732 bytes of a gzipped FileDescriptorProto // 710 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xdd, 0x4e, 0xe3, 0x46, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xdd, 0x4e, 0xdb, 0x4a,
0x14, 0x8e, 0x1d, 0x3b, 0x24, 0x27, 0x81, 0xd0, 0x81, 0x22, 0xab, 0x17, 0x2d, 0xb5, 0xb8, 0xa0, 0x10, 0x8e, 0x1d, 0x3b, 0x24, 0x93, 0x40, 0x38, 0x0b, 0x07, 0x59, 0xe7, 0xe2, 0x94, 0xae, 0xb8,
0xad, 0x14, 0x24, 0x90, 0xda, 0xaa, 0xea, 0x4d, 0x42, 0x91, 0x92, 0x0a, 0x28, 0x9d, 0xfd, 0xd1, 0xa0, 0xad, 0x14, 0x24, 0x90, 0xda, 0xaa, 0xea, 0x4d, 0x42, 0x91, 0x92, 0x0a, 0x28, 0xdd, 0xb6,
0xee, 0xde, 0x4d, 0x9c, 0x43, 0x98, 0x25, 0xb1, 0xcd, 0x78, 0x8c, 0xf0, 0xa3, 0xec, 0x9b, 0xec, 0x52, 0xdb, 0x3b, 0xc7, 0x19, 0xc2, 0x96, 0xc4, 0x36, 0xeb, 0x35, 0x22, 0x8f, 0xd2, 0x37, 0xe9,
0xd5, 0xbe, 0xc8, 0xbe, 0xcc, 0x6a, 0x7e, 0x92, 0x38, 0x81, 0xd5, 0x6a, 0x11, 0xda, 0x1b, 0x98, 0x55, 0x5f, 0xa4, 0x2f, 0x53, 0xed, 0x0f, 0x89, 0x13, 0xa8, 0xaa, 0x22, 0xd4, 0x1b, 0xd8, 0xf9,
0xf3, 0x9d, 0x33, 0x73, 0xbe, 0x7c, 0xe7, 0xc7, 0xd0, 0x1a, 0x8a, 0xe4, 0x1a, 0x45, 0x27, 0x15, 0x66, 0x76, 0x67, 0xf2, 0xcd, 0x7c, 0x63, 0x68, 0xf4, 0x45, 0x72, 0x8e, 0xa2, 0x95, 0x8a, 0x44,
0x89, 0x4c, 0x88, 0x2f, 0x8b, 0x14, 0xb3, 0xf0, 0xbd, 0x0b, 0xad, 0x9e, 0xc6, 0xbb, 0x91, 0xe4, 0x26, 0xc4, 0x97, 0x93, 0x14, 0x33, 0xfa, 0xcd, 0x85, 0x46, 0x47, 0xe3, 0xed, 0x48, 0xf2, 0x24,
0x49, 0x4c, 0x7e, 0x06, 0x8f, 0xc7, 0x5c, 0x06, 0xce, 0xae, 0xb3, 0xdf, 0x3c, 0x6c, 0x76, 0x74, 0x26, 0x0f, 0xc1, 0xe3, 0x31, 0x97, 0x81, 0xb3, 0xe9, 0x6c, 0xd7, 0x77, 0xeb, 0x2d, 0x1d, 0xd6,
0x58, 0x67, 0x10, 0x73, 0xd9, 0xaf, 0x50, 0xed, 0x22, 0x3d, 0x68, 0x0b, 0x1c, 0xf3, 0x4c, 0xa2, 0xea, 0xc5, 0x5c, 0x76, 0x4b, 0x4c, 0xbb, 0x48, 0x07, 0x9a, 0x02, 0x87, 0x3c, 0x93, 0x28, 0x0e,
0x38, 0xb9, 0xc3, 0x48, 0x26, 0x22, 0x70, 0x75, 0xf4, 0x8e, 0x8d, 0xa6, 0xcb, 0xde, 0x7e, 0x85, 0xae, 0x30, 0x92, 0x89, 0x08, 0x5c, 0x1d, 0xbd, 0x61, 0xa3, 0xd9, 0xbc, 0xb7, 0x5b, 0x62, 0x8b,
0xae, 0x5e, 0x20, 0x7b, 0xe0, 0xb3, 0x7c, 0xc4, 0x65, 0x50, 0xd5, 0x37, 0x5b, 0xf6, 0x66, 0x57, 0x17, 0xc8, 0x16, 0xf8, 0x61, 0x3e, 0xe0, 0x32, 0x28, 0xeb, 0x9b, 0x0d, 0x7b, 0xb3, 0xad, 0xb0,
0x61, 0xfd, 0x0a, 0x35, 0x4e, 0xf2, 0x2f, 0x6c, 0xe1, 0x94, 0xcb, 0x41, 0x2c, 0x51, 0x44, 0x57, 0x6e, 0x89, 0x19, 0x27, 0x79, 0x0d, 0x6b, 0x38, 0xe6, 0xb2, 0x17, 0x4b, 0x14, 0xd1, 0x59, 0xc8,
0x8c, 0xc7, 0x27, 0xb7, 0x18, 0xcb, 0xc0, 0x5b, 0xca, 0xb6, 0xe2, 0xed, 0x57, 0xe8, 0x43, 0x97, 0xe3, 0x83, 0x4b, 0x8c, 0x65, 0xe0, 0xcd, 0x65, 0x5b, 0xf0, 0x76, 0x4b, 0xec, 0xb6, 0x4b, 0xe4,
0xc8, 0xef, 0xd0, 0xcc, 0xd3, 0x11, 0x93, 0x38, 0x88, 0x47, 0x78, 0x17, 0xf8, 0xfa, 0x0d, 0x62, 0x29, 0xd4, 0xf3, 0x74, 0x10, 0x4a, 0xec, 0xc5, 0x03, 0xbc, 0x0a, 0x7c, 0xfd, 0x06, 0xb1, 0x6f,
0xdf, 0x78, 0xb1, 0xf0, 0xf4, 0x2b, 0xb4, 0x1c, 0x48, 0x36, 0xc0, 0x95, 0x45, 0x50, 0xdb, 0x75, 0x7c, 0x98, 0x79, 0xba, 0x25, 0x56, 0x0c, 0x24, 0x2b, 0xe0, 0xca, 0x49, 0x50, 0xd9, 0x74, 0xb6,
0xf6, 0x7d, 0xea, 0xca, 0xa2, 0xb7, 0x06, 0xfe, 0x2d, 0x9b, 0xe4, 0x18, 0xfe, 0x0d, 0x9e, 0x92, 0x7d, 0xe6, 0xca, 0x49, 0x67, 0x09, 0xfc, 0xcb, 0x70, 0x94, 0x23, 0x7d, 0x09, 0x9e, 0xa2, 0x85,
0x85, 0x6c, 0x83, 0x3f, 0xbc, 0xbb, 0x1a, 0x8c, 0xb4, 0x64, 0x0d, 0x6a, 0x0c, 0xf2, 0x23, 0x00, 0xac, 0x83, 0xdf, 0xbf, 0x3a, 0xeb, 0x0d, 0x34, 0x65, 0x35, 0x66, 0x0c, 0xf2, 0x3f, 0x40, 0x98,
0x4b, 0xd3, 0x63, 0x95, 0x7f, 0x30, 0xd2, 0xfa, 0x34, 0x68, 0x09, 0x09, 0x8f, 0xa0, 0xbd, 0x22, 0xa6, 0xfb, 0x2a, 0x7f, 0x6f, 0xa0, 0xf9, 0xa9, 0xb1, 0x02, 0x42, 0xf7, 0xa0, 0xb9, 0x40, 0x13,
0x13, 0xd9, 0x85, 0x26, 0x9a, 0xe3, 0x39, 0x9b, 0xa2, 0x7d, 0xae, 0x0c, 0x85, 0x5d, 0xf0, 0xb5, 0xd9, 0x84, 0x3a, 0x9a, 0xe3, 0x71, 0x38, 0x46, 0xfb, 0x5c, 0x11, 0xa2, 0x6d, 0xf0, 0x35, 0x43,
0x42, 0x5f, 0x0e, 0x25, 0x3b, 0x50, 0xcb, 0x24, 0x93, 0x79, 0x66, 0x73, 0x5b, 0x2b, 0x3c, 0x80, 0xbf, 0x0f, 0x25, 0x1b, 0x50, 0xc9, 0x64, 0x28, 0xf3, 0xcc, 0xe6, 0xb6, 0x16, 0xdd, 0x81, 0xc6,
0xd6, 0x45, 0x32, 0x99, 0xf0, 0x78, 0x6c, 0x64, 0xf9, 0x09, 0xbc, 0x29, 0x4a, 0xb6, 0x52, 0xef, 0x49, 0x32, 0x1a, 0xf1, 0x78, 0x68, 0x68, 0x79, 0x00, 0xde, 0x18, 0x65, 0xb8, 0xd0, 0xef, 0x23,
0x33, 0x94, 0x8c, 0x6a, 0x47, 0xf8, 0xc1, 0x81, 0x66, 0x49, 0x1e, 0x95, 0x3a, 0xc3, 0x9b, 0x1c, 0x94, 0x21, 0xd3, 0x0e, 0xfa, 0xdd, 0x81, 0x7a, 0x81, 0x1e, 0x95, 0x3a, 0xc3, 0x8b, 0x1c, 0xe3,
0xe3, 0x08, 0xcf, 0xf3, 0xa9, 0xbe, 0xe7, 0xd1, 0x32, 0x44, 0x42, 0x68, 0x8d, 0x32, 0xf9, 0x0c, 0x08, 0x8f, 0xf3, 0xb1, 0xbe, 0xe7, 0xb1, 0x22, 0x44, 0x28, 0x34, 0x06, 0x99, 0x7c, 0x87, 0xe2,
0xc5, 0x2d, 0x8f, 0x70, 0xf0, 0x8f, 0x25, 0xb0, 0x84, 0xa9, 0x98, 0x4c, 0x44, 0x8b, 0x98, 0xaa, 0x92, 0x47, 0xd8, 0x7b, 0x65, 0x0b, 0x98, 0xc3, 0x54, 0x4c, 0x26, 0xa2, 0x59, 0x4c, 0xd9, 0xc4,
0x89, 0x29, 0x63, 0x24, 0x80, 0x35, 0x81, 0x37, 0xcf, 0x8b, 0x14, 0x75, 0xc5, 0x3d, 0x3a, 0x33, 0x14, 0x31, 0x12, 0xc0, 0x92, 0xc0, 0x8b, 0xf7, 0x93, 0x14, 0x75, 0xc7, 0x3d, 0x76, 0x6d, 0x92,
0xc9, 0x6f, 0x50, 0x17, 0x98, 0xa5, 0x49, 0x9c, 0xa1, 0x2d, 0x64, 0x7b, 0xde, 0x7a, 0x06, 0xa6, 0x27, 0x50, 0x15, 0x98, 0xa5, 0x49, 0x9c, 0xa1, 0x6d, 0x64, 0x73, 0x3a, 0x7a, 0x06, 0x66, 0xd3,
0xf3, 0x80, 0xf0, 0xa3, 0x03, 0xed, 0xd5, 0x66, 0xd8, 0x06, 0x9f, 0xeb, 0x36, 0x30, 0xf4, 0x8d, 0x00, 0xfa, 0xc3, 0x81, 0xe6, 0xe2, 0x30, 0xac, 0x83, 0xcf, 0xf5, 0x18, 0x98, 0xf2, 0x8d, 0x71,
0xf1, 0x64, 0xc4, 0x09, 0x78, 0x72, 0xc1, 0x5a, 0x9f, 0x15, 0x76, 0x99, 0xc7, 0x91, 0xa6, 0xdb, 0x6f, 0x85, 0x13, 0xf0, 0xe4, 0xac, 0x6a, 0x7d, 0x56, 0xd8, 0x69, 0x1e, 0x47, 0xba, 0xdc, 0x1a,
0xa0, 0xfa, 0xac, 0x30, 0x26, 0xc6, 0x99, 0x6e, 0xae, 0x06, 0xd5, 0x67, 0x55, 0x37, 0xf5, 0x3f, 0xd3, 0x67, 0x85, 0x85, 0x62, 0x98, 0xe9, 0xe1, 0xaa, 0x31, 0x7d, 0x56, 0x7d, 0x53, 0xff, 0xa3,
0x1a, 0x06, 0x6b, 0xa6, 0x6e, 0xc6, 0x9a, 0xe1, 0x62, 0x18, 0xd4, 0x17, 0xb8, 0x18, 0x86, 0xef, 0x7e, 0xb0, 0x64, 0xfa, 0x66, 0xac, 0x6b, 0x5c, 0xf4, 0x83, 0xea, 0x0c, 0x17, 0x7d, 0xfa, 0xd5,
0x5c, 0xd8, 0xa4, 0x18, 0x21, 0x4f, 0xa5, 0x99, 0xe3, 0xd3, 0x64, 0xfc, 0xd0, 0x84, 0x3a, 0x8f, 0x85, 0x55, 0x86, 0x11, 0xf2, 0x54, 0x1a, 0x1d, 0x1f, 0x26, 0xc3, 0xdb, 0x14, 0xea, 0xdc, 0x59,
0x9e, 0x50, 0xf7, 0x11, 0x13, 0x5a, 0x7d, 0x82, 0x09, 0xf5, 0xbe, 0x6e, 0x42, 0xfd, 0xfb, 0x13, 0xa1, 0xee, 0x1d, 0x14, 0x5a, 0xbe, 0x07, 0x85, 0x7a, 0x7f, 0xa6, 0x50, 0xff, 0xa6, 0x42, 0x25,
0x2a, 0x61, 0xfb, 0xff, 0x1c, 0x45, 0xf1, 0x4d, 0xab, 0x1f, 0x76, 0x61, 0x4b, 0x27, 0x3c, 0x9e, 0xac, 0xbf, 0xcd, 0x51, 0x4c, 0xfe, 0x6a, 0xf7, 0x69, 0x1b, 0xd6, 0x74, 0xc2, 0xfd, 0x69, 0xc2,
0x27, 0x3c, 0xe5, 0x99, 0x24, 0xbf, 0x82, 0x37, 0xe1, 0x99, 0x5a, 0xac, 0xd5, 0xcf, 0x4b, 0x43, 0x43, 0x9e, 0x49, 0xf2, 0x18, 0xbc, 0x11, 0xcf, 0xd4, 0x62, 0x2d, 0xff, 0x9a, 0x1a, 0xa6, 0x63,
0x75, 0x4c, 0xd8, 0x86, 0x75, 0x4d, 0xfc, 0x9c, 0x4f, 0x2e, 0x98, 0x60, 0xd3, 0xf0, 0x3b, 0x68, 0x68, 0x13, 0x96, 0x75, 0xe1, 0xc7, 0x7c, 0x74, 0x12, 0x8a, 0x70, 0x4c, 0xff, 0x81, 0xa6, 0x06,
0x6b, 0xe0, 0xbf, 0x5c, 0x4a, 0x14, 0x6a, 0x3a, 0xc3, 0x4d, 0xd8, 0xb0, 0x3f, 0x2e, 0xb6, 0xc8, 0xde, 0xe4, 0x52, 0xa2, 0x50, 0xea, 0xa4, 0xab, 0xb0, 0x62, 0x7f, 0x5c, 0x6c, 0x91, 0x8f, 0x53,
0xab, 0x39, 0x72, 0x86, 0x59, 0xc6, 0xc6, 0x48, 0xf6, 0x60, 0x9d, 0xc7, 0x96, 0xd9, 0x05, 0xe3, 0xe4, 0x08, 0xb3, 0x2c, 0x1c, 0x22, 0xd9, 0x82, 0x65, 0x1e, 0xdb, 0xca, 0x4e, 0x42, 0x2e, 0xec,
0xc2, 0x2e, 0x8a, 0x65, 0x70, 0x75, 0xa2, 0xdd, 0x7b, 0x13, 0x1d, 0xbe, 0x5e, 0xa4, 0x7f, 0xea, 0xa2, 0x98, 0x07, 0x17, 0x15, 0xed, 0xde, 0x50, 0x34, 0xfd, 0x34, 0x4b, 0x7f, 0xdf, 0x4f, 0x77,
0xa7, 0x7b, 0x00, 0xa6, 0x6f, 0x07, 0xf1, 0x65, 0xf2, 0xc8, 0x5d, 0xfa, 0x16, 0x3c, 0x25, 0x00, 0x00, 0xcc, 0xdc, 0xf6, 0xe2, 0xd3, 0xe4, 0x8e, 0xbb, 0xf4, 0x0b, 0x78, 0x8a, 0x00, 0xf2, 0x68,
0xf9, 0x65, 0xbe, 0xcb, 0x94, 0xc4, 0xdf, 0x97, 0x76, 0x99, 0xfe, 0x73, 0x12, 0x4b, 0x51, 0x98, 0xba, 0xcb, 0x14, 0xc5, 0xff, 0x16, 0x76, 0x99, 0xfe, 0x73, 0x10, 0x4b, 0x31, 0x31, 0x5b, 0xed,
0xad, 0xf6, 0xc3, 0x1f, 0xd0, 0x98, 0x43, 0x64, 0x13, 0xaa, 0xd7, 0x58, 0xd8, 0x9c, 0xea, 0xa8, 0xbf, 0x67, 0x50, 0x9b, 0x42, 0x64, 0x15, 0xca, 0xe7, 0x38, 0xb1, 0x39, 0xd5, 0x51, 0xd5, 0xa1,
0x78, 0xe8, 0x16, 0xb2, 0x8c, 0x8d, 0xf1, 0x97, 0xfb, 0xa7, 0x13, 0xbe, 0x84, 0xfa, 0x6c, 0xc7, 0x47, 0xc8, 0x56, 0x6c, 0x8c, 0x17, 0xee, 0x73, 0x87, 0x52, 0xa8, 0x5e, 0xef, 0x98, 0xc2, 0x8e,
0x94, 0x76, 0xac, 0xa3, 0x9b, 0xcf, 0x5a, 0x6a, 0x71, 0x4d, 0x8d, 0x4c, 0x96, 0xec, 0xcc, 0x54, 0x75, 0xf4, 0xf0, 0x59, 0x6b, 0xb7, 0x0a, 0x15, 0xf3, 0xad, 0xed, 0xc0, 0xe7, 0x6a, 0xab, 0xb5,
0x9e, 0x94, 0x15, 0x93, 0x84, 0x8d, 0x74, 0xeb, 0xb4, 0xe8, 0xcc, 0x3c, 0xac, 0x43, 0xcd, 0x7c, 0xa3, 0xeb, 0xe8, 0x57, 0xf4, 0x87, 0x77, 0xef, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2a, 0x8f,
0x9f, 0x7b, 0xf0, 0xa6, 0xde, 0xe9, 0x1c, 0x68, 0xee, 0xc3, 0x9a, 0xfe, 0x58, 0x1f, 0x7d, 0x0a, 0x2d, 0x0d, 0x88, 0x07, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xb2, 0x03, 0x83, 0x52, 0xbc, 0x07, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment