From 66a185eac8860ab5cdd9f689d3ea241d040d96da Mon Sep 17 00:00:00 2001 From: Rzy <465386466@qq.com> Date: Tue, 9 Jul 2024 18:19:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=9E=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/api/doc/api.api | 8 + cmd/api/doc/vo/base.api | 12 + cmd/api/internal/config/config.go | 3 + cmd/api/internal/handler/routes.go | 12 + .../handler/transfer/notifyCouponHandler.go | 28 + .../handler/transfer/notifyGrantHandler.go | 29 + cmd/api/internal/logic/do/notify.go | 27 + .../internal/logic/transfer/marketLogic.go | 3 + .../logic/transfer/notifyCouponLogic.go | 38 ++ .../logic/transfer/notifyGrantLogic.go | 38 ++ cmd/api/internal/svc/serviceContext.go | 4 +- cmd/api/internal/types/extraTypes.go | 9 +- cmd/api/internal/types/types.go | 14 + genModel/merchantWechatModel.go | 29 + genModel/merchantWechatModel_gen.go | 102 +++ genModel/serverOrderModel.go | 29 + genModel/serverOrderModel_gen.go | 110 +++ rpc/transfer.proto | 12 +- rpc/transfer/transfer.pb.go | 633 +++++++++--------- untils/request/request.go | 130 ++++ untils/request/test/wxbiz_test.go | 83 +++ 21 files changed, 1031 insertions(+), 322 deletions(-) create mode 100644 cmd/api/internal/handler/transfer/notifyCouponHandler.go create mode 100644 cmd/api/internal/handler/transfer/notifyGrantHandler.go create mode 100644 cmd/api/internal/logic/do/notify.go create mode 100644 cmd/api/internal/logic/transfer/notifyCouponLogic.go create mode 100644 cmd/api/internal/logic/transfer/notifyGrantLogic.go create mode 100755 genModel/merchantWechatModel.go create mode 100755 genModel/merchantWechatModel_gen.go create mode 100755 genModel/serverOrderModel.go create mode 100755 genModel/serverOrderModel_gen.go create mode 100644 untils/request/request.go create mode 100644 untils/request/test/wxbiz_test.go diff --git a/cmd/api/doc/api.api b/cmd/api/doc/api.api index 0c6596e..dc3a070 100755 --- a/cmd/api/doc/api.api +++ b/cmd/api/doc/api.api @@ -21,5 +21,13 @@ service transfer { @doc "荣数立减金发放" @handler market post /coupon/grant (Req) returns (Resp) + + @doc "荣数回调" + @handler notifyGrant + post /notify/grant (NotifyGrantReq) returns (string) + + @doc "荣数回调" + @handler notifyCoupon + post /notify/coupon (NotifyCouponReq) returns (string) } diff --git a/cmd/api/doc/vo/base.api b/cmd/api/doc/vo/base.api index 317bc2d..8225dea 100755 --- a/cmd/api/doc/vo/base.api +++ b/cmd/api/doc/vo/base.api @@ -37,3 +37,15 @@ type RespDataVocherInfo{ } +type NotifyGrantReq{ + SipOrderNo string `json:"sipOrderNo"` + Data string `json:"data"` + Sign string `json:"sign"` +} + +type NotifyCouponReq{ + SipOrderNo string `json:"sipOrderNo"` + Data string `json:"data"` + Sign string `json:"sign"` +} + diff --git a/cmd/api/internal/config/config.go b/cmd/api/internal/config/config.go index 2a41aea..b33b6d9 100755 --- a/cmd/api/internal/config/config.go +++ b/cmd/api/internal/config/config.go @@ -12,6 +12,9 @@ type Config struct { Coupon struct { DataSource string } + Transfer struct { + DataSource string + } } Cache cache.CacheConf } diff --git a/cmd/api/internal/handler/routes.go b/cmd/api/internal/handler/routes.go index f9840a4..3777799 100644 --- a/cmd/api/internal/handler/routes.go +++ b/cmd/api/internal/handler/routes.go @@ -19,6 +19,18 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/coupon/grant", Handler: transfer.MarketHandler(serverCtx), }, + { + // 荣数回调 + Method: http.MethodPost, + Path: "/notify/coupon", + Handler: transfer.NotifyCouponHandler(serverCtx), + }, + { + // 荣数回调 + Method: http.MethodPost, + Path: "/notify/grant", + Handler: transfer.NotifyGrantHandler(serverCtx), + }, }, rest.WithPrefix("/cross/v1"), ) diff --git a/cmd/api/internal/handler/transfer/notifyCouponHandler.go b/cmd/api/internal/handler/transfer/notifyCouponHandler.go new file mode 100644 index 0000000..b271a0a --- /dev/null +++ b/cmd/api/internal/handler/transfer/notifyCouponHandler.go @@ -0,0 +1,28 @@ +package transfer + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "rs/cmd/api/internal/logic/transfer" + "rs/cmd/api/internal/svc" + "rs/cmd/api/internal/types" +) + +// 荣数回调 +func NotifyCouponHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.NotifyCouponReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + l := transfer.NewNotifyCouponLogic(r.Context(), svcCtx) + resp, err := l.NotifyCoupon(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/cmd/api/internal/handler/transfer/notifyGrantHandler.go b/cmd/api/internal/handler/transfer/notifyGrantHandler.go new file mode 100644 index 0000000..fafd990 --- /dev/null +++ b/cmd/api/internal/handler/transfer/notifyGrantHandler.go @@ -0,0 +1,29 @@ +package transfer + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "rs/cmd/api/internal/logic/transfer" + "rs/cmd/api/internal/svc" + "rs/cmd/api/internal/types" +) + +// 荣数回调 +func NotifyGrantHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.NotifyGrantReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := transfer.NewNotifyGrantLogic(r.Context(), svcCtx) + resp, err := l.NotifyGrant(&req) + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/cmd/api/internal/logic/do/notify.go b/cmd/api/internal/logic/do/notify.go new file mode 100644 index 0000000..1f31e98 --- /dev/null +++ b/cmd/api/internal/logic/do/notify.go @@ -0,0 +1,27 @@ +package do + +import ( + "context" + "encoding/json" + "rs/cmd/api/internal/svc" + "rs/cmd/api/internal/types" +) + +func NotifyInfo(req any, SipOrderNo string, svcCtx *svc.ServiceContext, ctx context.Context) (notify types.NotifyTypes, requestBody map[string]string, err error) { + requestBody = make(map[string]string, 3) + reqJson, _ := json.Marshal(req) + _ = json.Unmarshal(reqJson, &requestBody) + orderInfo, err := svcCtx.TransferOrder.FindByOutBizNo(ctx, SipOrderNo) + if err != nil { + return notify, requestBody, err + } + merchantInfo, err := svcCtx.MerchantWechat.FindOneByMerchantId(ctx, orderInfo.VoucherNum) + if err != nil { + return notify, requestBody, err + } + err = json.Unmarshal([]byte(merchantInfo.NotifyUrl.String), ¬ify) + if err != nil { + return notify, requestBody, err + } + return notify, requestBody, err +} diff --git a/cmd/api/internal/logic/transfer/marketLogic.go b/cmd/api/internal/logic/transfer/marketLogic.go index f665247..468d23a 100755 --- a/cmd/api/internal/logic/transfer/marketLogic.go +++ b/cmd/api/internal/logic/transfer/marketLogic.go @@ -36,6 +36,9 @@ func (l *MarketLogic) Market(req *types.Req) (resp *types.Resp, err error) { DecryptData, _ := l.Decrypt(req.VendorNo, req.Data) _ = copier.Copy(&reqData, &req) tagLen := len(DecryptData.VoucherTag) + reqData.OutBizNo = DecryptData.SipOrderNo + reqData.Num = DecryptData.Num + if tagLen < 6 { //如果没有解析出来,直接投递给荣数,让荣数自行处理转发 result, _err := l.svcCtx.TransferRpc.RsCouponGrant(l.ctx, &reqData) diff --git a/cmd/api/internal/logic/transfer/notifyCouponLogic.go b/cmd/api/internal/logic/transfer/notifyCouponLogic.go new file mode 100644 index 0000000..c9d9857 --- /dev/null +++ b/cmd/api/internal/logic/transfer/notifyCouponLogic.go @@ -0,0 +1,38 @@ +package transfer + +import ( + "context" + "rs/cmd/api/internal/logic/do" + "rs/untils/request" + + "rs/cmd/api/internal/svc" + "rs/cmd/api/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type NotifyCouponLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// 荣数回调 +func NewNotifyCouponLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NotifyCouponLogic { + return &NotifyCouponLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *NotifyCouponLogic) NotifyCoupon(req *types.NotifyCouponReq) (resp string, err error) { + notify, requestBody, err := do.NotifyInfo(req, req.SipOrderNo, l.svcCtx, l.ctx) + _req := request.Request{ + Method: "POST", + Url: notify.Coupon, + Json: requestBody, + } + _resp, _ := _req.Send() + return _resp.Text, nil +} diff --git a/cmd/api/internal/logic/transfer/notifyGrantLogic.go b/cmd/api/internal/logic/transfer/notifyGrantLogic.go new file mode 100644 index 0000000..919bf19 --- /dev/null +++ b/cmd/api/internal/logic/transfer/notifyGrantLogic.go @@ -0,0 +1,38 @@ +package transfer + +import ( + "context" + "rs/cmd/api/internal/logic/do" + "rs/untils/request" + + "rs/cmd/api/internal/svc" + "rs/cmd/api/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type NotifyGrantLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// 荣数回调 +func NewNotifyGrantLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NotifyGrantLogic { + return &NotifyGrantLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *NotifyGrantLogic) NotifyGrant(req *types.NotifyGrantReq) (resp string, err error) { + notify, requestBody, err := do.NotifyInfo(req, req.SipOrderNo, l.svcCtx, l.ctx) + _req := request.Request{ + Method: "POST", + Url: notify.Grant, + Json: requestBody, + } + _resp, _ := _req.Send() + return _resp.Text, nil +} diff --git a/cmd/api/internal/svc/serviceContext.go b/cmd/api/internal/svc/serviceContext.go index 6339c76..ea3a869 100755 --- a/cmd/api/internal/svc/serviceContext.go +++ b/cmd/api/internal/svc/serviceContext.go @@ -21,12 +21,14 @@ func NewServiceContext(c config.Config) *ServiceContext { }) sqlConn := sqlx.NewMysql(c.DB.Coupon.DataSource) client := transferClient.NewTransfer(conn) - + transConn := sqlx.NewMysql(c.DB.Transfer.DataSource) base := types.BaseServiceContext{ Config: c, TransferRpc: client, + TransferOrder: genModel.NewServerOrderModel(transConn), ProductRedirectConf: genModel.NewProductRedirectConfModel(sqlConn, c.Cache), Merchant: genModel.NewMerchantModel(sqlConn, c.Cache), + MerchantWechat: genModel.NewMerchantWechatModel(sqlConn), } return &ServiceContext{ BaseServiceContext: &base, diff --git a/cmd/api/internal/types/extraTypes.go b/cmd/api/internal/types/extraTypes.go index f26d178..018bf6d 100644 --- a/cmd/api/internal/types/extraTypes.go +++ b/cmd/api/internal/types/extraTypes.go @@ -11,6 +11,8 @@ type BaseServiceContext struct { TransferRpc transferClient.Transfer // 调用transfer服务 ProductRedirectConf genModel.ProductRedirectConfModel Merchant genModel.MerchantModel + TransferOrder genModel.ServerOrderModel + MerchantWechat genModel.MerchantWechatModel } type DecryptReqData struct { @@ -19,5 +21,10 @@ type DecryptReqData struct { AccountType int32 `json:"accountType"` AccountNo string `json:"accountNo"` AccountInfo string `json:"accountInfo,optional"` - Num int `json:"num"` + Num int32 `json:"num"` +} + +type NotifyTypes struct { + Coupon string `json:"coupon_grant_order"` + Grant string `json:"wechat_coupon_status"` } diff --git a/cmd/api/internal/types/types.go b/cmd/api/internal/types/types.go index 1ee113b..6aa5ceb 100644 --- a/cmd/api/internal/types/types.go +++ b/cmd/api/internal/types/types.go @@ -4,6 +4,18 @@ package types type Empty struct { } +type NotifyCouponReq struct { + SipOrderNo string `json:"sipOrderNo"` + Data string `json:"data"` + Sign string `json:"sign"` +} + +type NotifyGrantReq struct { + SipOrderNo string `json:"sipOrderNo"` + Data string `json:"data"` + Sign string `json:"sign"` +} + type Req struct { VendorNo string `json:"vendorNo"` Data string `json:"data"` @@ -31,3 +43,5 @@ type RespDataVocherInfo struct { StartTime string `json:"startTime"` EndTime string `json:"endTime"` } + + diff --git a/genModel/merchantWechatModel.go b/genModel/merchantWechatModel.go new file mode 100755 index 0000000..1429649 --- /dev/null +++ b/genModel/merchantWechatModel.go @@ -0,0 +1,29 @@ +package genModel + +import "github.com/zeromicro/go-zero/core/stores/sqlx" + +var _ MerchantWechatModel = (*customMerchantWechatModel)(nil) + +type ( + // MerchantWechatModel is an interface to be customized, add more methods here, + // and implement the added methods in customMerchantWechatModel. + MerchantWechatModel interface { + merchantWechatModel + withSession(session sqlx.Session) MerchantWechatModel + } + + customMerchantWechatModel struct { + *defaultMerchantWechatModel + } +) + +// NewMerchantWechatModel returns a model for the database table. +func NewMerchantWechatModel(conn sqlx.SqlConn) MerchantWechatModel { + return &customMerchantWechatModel{ + defaultMerchantWechatModel: newMerchantWechatModel(conn), + } +} + +func (m *customMerchantWechatModel) withSession(session sqlx.Session) MerchantWechatModel { + return NewMerchantWechatModel(sqlx.NewSqlConnFromSession(session)) +} diff --git a/genModel/merchantWechatModel_gen.go b/genModel/merchantWechatModel_gen.go new file mode 100755 index 0000000..f83ddc2 --- /dev/null +++ b/genModel/merchantWechatModel_gen.go @@ -0,0 +1,102 @@ +// Code generated by goctl. DO NOT EDIT. + +package genModel + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + merchantWechatFieldNames = builder.RawFieldNames(&MerchantWechat{}) + merchantWechatRows = strings.Join(merchantWechatFieldNames, ",") + merchantWechatRowsExpectAutoSet = strings.Join(stringx.Remove(merchantWechatFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + merchantWechatRowsWithPlaceHolder = strings.Join(stringx.Remove(merchantWechatFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + merchantWechatModel interface { + Insert(ctx context.Context, data *MerchantWechat) (sql.Result, error) + FindOne(ctx context.Context, id uint64) (*MerchantWechat, error) + Update(ctx context.Context, data *MerchantWechat) error + Delete(ctx context.Context, id uint64) error + FindOneByMerchantId(ctx context.Context, merchant_id string) (*MerchantWechat, error) + } + + defaultMerchantWechatModel struct { + conn sqlx.SqlConn + table string + } + + MerchantWechat struct { + Id uint64 `db:"id"` + MerchantId sql.NullString `db:"merchant_id"` // 商户号 + WechatMerchantId sql.NullString `db:"wechat_merchant_id"` // sip的微信商户号 + WechatAppId sql.NullString `db:"wechat_app_id"` // sip的微信app_id [{"appid" :"xxxxx", "default": "1"}]支持设置多个appid 但是只能设置一个default = 1, 代码当前商户正在用的appid。 如果需要使用其他appid发券 , 那么需要商户侧通过接口传入appid + NotifyUrl sql.NullString `db:"notify_url"` // 回调通知地址[{"coupon_grant_order":"xxxx"},{"wechat_coupon_status":"xxxxx"}] + CreateTime sql.NullTime `db:"create_time"` + } +) + +func newMerchantWechatModel(conn sqlx.SqlConn) *defaultMerchantWechatModel { + return &defaultMerchantWechatModel{ + conn: conn, + table: "`merchant_wechat`", + } +} + +func (m *defaultMerchantWechatModel) Delete(ctx context.Context, id uint64) error { + query := fmt.Sprintf("delete from %s where `id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, id) + return err +} + +func (m *defaultMerchantWechatModel) FindOne(ctx context.Context, id uint64) (*MerchantWechat, error) { + query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", merchantWechatRows, m.table) + var resp MerchantWechat + err := m.conn.QueryRowCtx(ctx, &resp, query, id) + switch err { + case nil: + return &resp, nil + case sqlx.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultMerchantWechatModel) FindOneByMerchantId(ctx context.Context, merchant_id string) (*MerchantWechat, error) { + query := fmt.Sprintf("select %s from %s where `merchant_id` = ? limit 1", merchantWechatRows, m.table) + var resp MerchantWechat + err := m.conn.QueryRowCtx(ctx, &resp, query, merchant_id) + switch err { + case nil: + return &resp, nil + case sqlx.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultMerchantWechatModel) Insert(ctx context.Context, data *MerchantWechat) (sql.Result, error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?)", m.table, merchantWechatRowsExpectAutoSet) + ret, err := m.conn.ExecCtx(ctx, query, data.MerchantId, data.WechatMerchantId, data.WechatAppId, data.NotifyUrl) + return ret, err +} + +func (m *defaultMerchantWechatModel) Update(ctx context.Context, data *MerchantWechat) error { + query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, merchantWechatRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, data.MerchantId, data.WechatMerchantId, data.WechatAppId, data.NotifyUrl, data.Id) + return err +} + +func (m *defaultMerchantWechatModel) tableName() string { + return m.table +} diff --git a/genModel/serverOrderModel.go b/genModel/serverOrderModel.go new file mode 100755 index 0000000..3596418 --- /dev/null +++ b/genModel/serverOrderModel.go @@ -0,0 +1,29 @@ +package genModel + +import "github.com/zeromicro/go-zero/core/stores/sqlx" + +var _ ServerOrderModel = (*customServerOrderModel)(nil) + +type ( + // ServerOrderModel is an interface to be customized, add more methods here, + // and implement the added methods in customServerOrderModel. + ServerOrderModel interface { + serverOrderModel + withSession(session sqlx.Session) ServerOrderModel + } + + customServerOrderModel struct { + *defaultServerOrderModel + } +) + +// NewServerOrderModel returns a model for the database table. +func NewServerOrderModel(conn sqlx.SqlConn) ServerOrderModel { + return &customServerOrderModel{ + defaultServerOrderModel: newServerOrderModel(conn), + } +} + +func (m *customServerOrderModel) withSession(session sqlx.Session) ServerOrderModel { + return NewServerOrderModel(sqlx.NewSqlConnFromSession(session)) +} diff --git a/genModel/serverOrderModel_gen.go b/genModel/serverOrderModel_gen.go new file mode 100755 index 0000000..47be7f7 --- /dev/null +++ b/genModel/serverOrderModel_gen.go @@ -0,0 +1,110 @@ +// Code generated by goctl. DO NOT EDIT. + +package genModel + +import ( + "context" + "database/sql" + "fmt" + "strings" + "time" + + "github.com/zeromicro/go-zero/core/stores/builder" + "github.com/zeromicro/go-zero/core/stores/sqlx" + "github.com/zeromicro/go-zero/core/stringx" +) + +var ( + serverOrderFieldNames = builder.RawFieldNames(&ServerOrder{}) + serverOrderRows = strings.Join(serverOrderFieldNames, ",") + serverOrderRowsExpectAutoSet = strings.Join(stringx.Remove(serverOrderFieldNames, "`order_id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",") + serverOrderRowsWithPlaceHolder = strings.Join(stringx.Remove(serverOrderFieldNames, "`order_id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?" +) + +type ( + serverOrderModel interface { + Insert(ctx context.Context, data *ServerOrder) (sql.Result, error) + FindOne(ctx context.Context, orderId uint64) (*ServerOrder, error) + Update(ctx context.Context, data *ServerOrder) error + Delete(ctx context.Context, orderId uint64) error + FindByOutBizNo(ctx context.Context, out_biz_no string) (*ServerOrder, error) + + } + + defaultServerOrderModel struct { + conn sqlx.SqlConn + table string + } + + ServerOrder struct { + OrderId uint64 `db:"order_id"` + PlatformId int64 `db:"platform_id"` // 下游平台id + OutBizNo string `db:"out_biz_no"` // 用户侧流水号 + VoucherNum string `db:"voucher_num"` // 商户号 + OrderNum string `db:"order_num"` // 系统侧订单号 + ProductId int64 `db:"product_id"` // 平台提供商品id + Num int64 `db:"num"` // 购买数量 + LogId sql.NullInt64 `db:"log_id"` // 对应的日志id + ReqTime time.Time `db:"req_time"` // 请求时间 + CreateTime time.Time `db:"create_time"` + UpdateTime time.Time `db:"update_time"` + Status int64 `db:"status"` // 状态 + } +) + +func newServerOrderModel(conn sqlx.SqlConn) *defaultServerOrderModel { + return &defaultServerOrderModel{ + conn: conn, + table: "`server_order`", + } +} + +func (m *defaultServerOrderModel) Delete(ctx context.Context, orderId uint64) error { + query := fmt.Sprintf("delete from %s where `order_id` = ?", m.table) + _, err := m.conn.ExecCtx(ctx, query, orderId) + return err +} + +func (m *defaultServerOrderModel) FindOne(ctx context.Context, orderId uint64) (*ServerOrder, error) { + query := fmt.Sprintf("select %s from %s where `order_id` = ? limit 1", serverOrderRows, m.table) + var resp ServerOrder + err := m.conn.QueryRowCtx(ctx, &resp, query, orderId) + switch err { + case nil: + return &resp, nil + case sqlx.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultServerOrderModel) FindByOutBizNo(ctx context.Context, out_biz_no string) (*ServerOrder, error) { + query := fmt.Sprintf("select %s from %s where `out_biz_no` = ? limit 1", serverOrderRows, m.table) + var resp ServerOrder + err := m.conn.QueryRowCtx(ctx, &resp, query, out_biz_no) + switch err { + case nil: + return &resp, nil + case sqlx.ErrNotFound: + return nil, ErrNotFound + default: + return nil, err + } +} + +func (m *defaultServerOrderModel) Insert(ctx context.Context, data *ServerOrder) (sql.Result, error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, serverOrderRowsExpectAutoSet) + ret, err := m.conn.ExecCtx(ctx, query, data.PlatformId, data.OutBizNo, data.VoucherNum, data.OrderNum, data.ProductId, data.Num, data.LogId, data.ReqTime, data.Status) + return ret, err +} + +func (m *defaultServerOrderModel) Update(ctx context.Context, data *ServerOrder) error { + query := fmt.Sprintf("update %s set %s where `order_id` = ?", m.table, serverOrderRowsWithPlaceHolder) + _, err := m.conn.ExecCtx(ctx, query, data.PlatformId, data.OutBizNo, data.VoucherNum, data.OrderNum, data.ProductId, data.Num, data.LogId, data.ReqTime, data.Status, data.OrderId) + return err +} + +func (m *defaultServerOrderModel) tableName() string { + return m.table +} diff --git a/rpc/transfer.proto b/rpc/transfer.proto index 45dbf69..a6fdd84 100644 --- a/rpc/transfer.proto +++ b/rpc/transfer.proto @@ -38,15 +38,9 @@ service Transfer { message RsCouponGrantReq { string vendorNo = 1; string data = 2; -// message Data{ -// string sipOrderNo = 1; -// string voucherTag = 2; -// int32 accountType = 3; -// string accountNo = 4; -// string accountInfo = 5; -// int32 num = 6; -// } - string sign = 3; + string out_biz_no = 3; + int32 num=4; + string sign = 5; } diff --git a/rpc/transfer/transfer.pb.go b/rpc/transfer/transfer.pb.go index d68b413..ba0432c 100644 --- a/rpc/transfer/transfer.pb.go +++ b/rpc/transfer/transfer.pb.go @@ -145,15 +145,9 @@ type RsCouponGrantReq struct { VendorNo string `protobuf:"bytes,1,opt,name=vendorNo,proto3" json:"vendorNo,omitempty"` Data string `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - // message Data{ - // string sipOrderNo = 1; - // string voucherTag = 2; - // int32 accountType = 3; - // string accountNo = 4; - // string accountInfo = 5; - // int32 num = 6; - // } - Sign string `protobuf:"bytes,3,opt,name=sign,proto3" json:"sign,omitempty"` + OutBizNo string `protobuf:"bytes,3,opt,name=out_biz_no,json=outBizNo,proto3" json:"out_biz_no,omitempty"` + Num int32 `protobuf:"varint,4,opt,name=num,proto3" json:"num,omitempty"` + Sign string `protobuf:"bytes,5,opt,name=sign,proto3" json:"sign,omitempty"` } func (x *RsCouponGrantReq) Reset() { @@ -202,6 +196,20 @@ func (x *RsCouponGrantReq) GetData() string { return "" } +func (x *RsCouponGrantReq) GetOutBizNo() string { + if x != nil { + return x.OutBizNo + } + return "" +} + +func (x *RsCouponGrantReq) GetNum() int32 { + if x != nil { + return x.Num + } + return 0 +} + func (x *RsCouponGrantReq) GetSign() string { if x != nil { return x.Sign @@ -2040,319 +2048,322 @@ var file_transfer_proto_rawDesc = []byte{ 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x22, 0x56, 0x0a, 0x10, 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, - 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x65, - 0x6e, 0x64, 0x6f, 0x72, 0x4e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, 0x65, - 0x6e, 0x64, 0x6f, 0x72, 0x4e, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, - 0x67, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x22, 0xff, - 0x03, 0x0a, 0x10, 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x33, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x2e, 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0xef, - 0x02, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x70, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x69, 0x70, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x12, 0x24, 0x0a, 0x0d, 0x76, 0x65, 0x6e, 0x64, 0x6f, - 0x72, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x12, 0x4d, 0x0a, - 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x52, 0x73, - 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x2e, 0x44, - 0x61, 0x74, 0x61, 0x2e, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0xd1, 0x01, 0x0a, - 0x0b, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b, - 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x28, - 0x0a, 0x0f, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, - 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x76, 0x6f, 0x75, 0x63, - 0x68, 0x65, 0x72, 0x44, 0x65, 0x73, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, - 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x44, 0x65, 0x73, 0x63, 0x12, 0x1c, 0x0a, 0x09, 0x71, 0x72, - 0x43, 0x6f, 0x64, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x71, - 0x72, 0x43, 0x6f, 0x64, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, - 0x22, 0xe0, 0x01, 0x0a, 0x0e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, - 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, - 0x31, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x1a, 0x6f, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x6f, - 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x6f, 0x75, - 0x63, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x0a, 0x0e, - 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x22, 0xf1, 0x01, 0x0a, 0x0e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x67, - 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x71, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x0a, 0x06, - 0x6d, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x65, - 0x6d, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x72, 0x65, 0x71, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x61, - 0x6c, 0x5f, 0x6e, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x53, - 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x6f, 0x75, 0x63, 0x68, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, - 0x63, 0x6f, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, - 0x68, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0xff, 0x01, 0x0a, 0x13, 0x4d, 0x61, 0x72, 0x6b, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x12, - 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x36, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x44, 0x69, - 0x73, 0x63, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x1a, 0x83, 0x01, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, - 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x76, - 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x21, - 0x0a, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x44, 0x61, 0x74, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xf6, 0x01, 0x0a, 0x13, 0x4d, 0x61, - 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x52, 0x65, - 0x71, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x19, 0x0a, 0x08, - 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x72, 0x65, 0x71, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x5f, 0x69, - 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x22, - 0x0a, 0x0d, 0x72, 0x65, 0x71, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, - 0x4e, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x21, 0x0a, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, - 0x64, 0x65, 0x22, 0xc2, 0x02, 0x0a, 0x10, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, - 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, - 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, - 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6d, 0x73, 0x67, 0x12, 0x33, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, - 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x2e, 0x44, 0x61, - 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0xcc, 0x01, 0x0a, 0x04, 0x44, 0x61, 0x74, - 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x64, + 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x22, 0x86, 0x01, 0x0a, 0x10, 0x52, 0x73, 0x43, 0x6f, 0x75, + 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x76, + 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x4e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x76, + 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x4e, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x0a, 0x6f, + 0x75, 0x74, 0x5f, 0x62, 0x69, 0x7a, 0x5f, 0x6e, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x6f, 0x75, 0x74, 0x42, 0x69, 0x7a, 0x4e, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x6e, 0x75, 0x6d, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x73, + 0x69, 0x67, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x22, + 0xff, 0x03, 0x0a, 0x10, 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x33, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x65, 0x72, 0x2e, 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, + 0xef, 0x02, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x70, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x69, + 0x70, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x12, 0x24, 0x0a, 0x0d, 0x76, 0x65, 0x6e, 0x64, + 0x6f, 0x72, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x12, 0x4d, + 0x0a, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x52, + 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x2e, + 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0xd1, 0x01, + 0x0a, 0x0b, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, + 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, + 0x28, 0x0a, 0x0f, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, + 0x72, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x76, 0x6f, 0x75, + 0x63, 0x68, 0x65, 0x72, 0x44, 0x65, 0x73, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x44, 0x65, 0x73, 0x63, 0x12, 0x1c, 0x0a, 0x09, 0x71, + 0x72, 0x43, 0x6f, 0x64, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x71, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, + 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, + 0x65, 0x22, 0xe0, 0x01, 0x0a, 0x0e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x52, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, + 0x12, 0x31, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x1a, 0x6f, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x76, + 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x6f, + 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x0a, + 0x0e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x22, 0xf1, 0x01, 0x0a, 0x0e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, + 0x67, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x71, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x0a, + 0x06, 0x6d, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, + 0x65, 0x6d, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x72, 0x65, 0x71, 0x5f, 0x73, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x71, + 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x6f, 0x75, 0x63, + 0x68, 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, + 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, + 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x22, 0xff, 0x01, 0x0a, 0x13, 0x4d, 0x61, 0x72, + 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x36, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x44, + 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x1a, 0x83, 0x01, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, + 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, + 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, + 0x21, 0x0a, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x44, 0x61, + 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xf6, 0x01, 0x0a, 0x13, 0x4d, + 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x19, 0x0a, + 0x08, 0x72, 0x65, 0x71, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x72, 0x65, 0x71, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x5f, + 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x65, 0x6d, 0x49, 0x64, 0x12, + 0x22, 0x0a, 0x0d, 0x72, 0x65, 0x71, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x53, 0x65, 0x72, 0x69, 0x61, + 0x6c, 0x4e, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, - 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x75, 0x72, 0x6c, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x55, 0x72, 0x6c, - 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x64, 0x61, 0x74, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, - 0x53, 0x64, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, - 0x5f, 0x65, 0x64, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x76, 0x6f, - 0x75, 0x63, 0x68, 0x65, 0x72, 0x45, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, - 0x64, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, - 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xc0, 0x02, 0x0a, 0x10, 0x4d, 0x61, 0x72, 0x6b, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, 0x06, - 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, - 0x70, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x71, 0x43, 0x6f, - 0x64, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x6d, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x72, 0x65, 0x71, - 0x5f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x72, 0x65, 0x71, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x6f, 0x12, 0x1c, 0x0a, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x15, 0x0a, 0x06, 0x70, - 0x6f, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x6f, 0x73, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x6e, 0x75, 0x6d, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x4e, - 0x75, 0x6d, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x6f, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x12, - 0x19, 0x0a, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x73, 0x65, 0x6e, 0x64, 0x4d, 0x73, 0x67, 0x22, 0x9c, 0x02, 0x0a, 0x16, 0x5a, - 0x6c, 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, - 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, - 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x1a, 0x8d, 0x01, 0x0a, 0x07, 0x50, 0x72, - 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, - 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, - 0x74, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x72, - 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, - 0x65, 0x6c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x74, 0x65, 0x6d, 0x4e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x74, 0x65, 0x6d, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x50, - 0x72, 0x69, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, - 0x69, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x22, 0x43, 0x0a, 0x13, 0x5a, 0x6c, 0x74, - 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, - 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x77, - 0x0a, 0x0f, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x6d, 0x73, 0x52, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x43, + 0x6f, 0x64, 0x65, 0x22, 0xc2, 0x02, 0x0a, 0x10, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, + 0x79, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x43, + 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x72, 0x72, 0x43, 0x6f, + 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6d, 0x73, 0x67, 0x12, 0x33, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, + 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x2e, 0x44, + 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0xcc, 0x01, 0x0a, 0x04, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, + 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x75, 0x72, + 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x55, 0x72, + 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x64, 0x61, + 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, + 0x72, 0x53, 0x64, 0x61, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, + 0x72, 0x5f, 0x65, 0x64, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x76, + 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x45, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, + 0x6f, 0x64, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x63, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xc0, 0x02, 0x0a, 0x10, 0x4d, 0x61, 0x72, + 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x12, 0x15, 0x0a, + 0x06, 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, + 0x70, 0x70, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x71, 0x43, + 0x6f, 0x64, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x72, 0x65, + 0x71, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x6f, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x15, 0x0a, 0x06, + 0x70, 0x6f, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x6f, + 0x73, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, + 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x6e, 0x75, + 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, + 0x4e, 0x75, 0x6d, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x6f, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x4e, 0x6f, + 0x12, 0x19, 0x0a, 0x08, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x6e, 0x64, 0x4d, 0x73, 0x67, 0x22, 0x9c, 0x02, 0x0a, 0x16, + 0x5a, 0x6c, 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x52, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x73, 0x1a, 0x8d, 0x01, 0x0a, 0x07, 0x50, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x50, + 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x6e, + 0x6e, 0x65, 0x6c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x74, 0x65, 0x6d, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x74, 0x65, 0x6d, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x69, 0x63, 0x65, 0x22, 0x43, 0x0a, 0x13, 0x5a, 0x6c, + 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, - 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, - 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0x83, 0x01, 0x0a, 0x0f, 0x5a, 0x6c, 0x74, 0x78, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, - 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x1e, 0x0a, + 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x22, + 0x77, 0x0a, 0x0f, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x6d, 0x73, 0x52, + 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x54, + 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, + 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0x83, 0x01, 0x0a, 0x0f, 0x5a, 0x6c, 0x74, + 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, + 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, + 0x67, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x1e, + 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0x7d, + 0x0a, 0x15, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0x7d, 0x0a, - 0x15, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x51, 0x75, + 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0x89, 0x01, + 0x0a, 0x15, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, + 0x61, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6d, 0x65, 0x72, + 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x75, 0x74, + 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, + 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0xbc, 0x02, 0x0a, 0x10, 0x5a, 0x6c, + 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x1e, + 0x0a, 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, + 0x67, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, + 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x16, + 0x0a, 0x06, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x28, + 0x0a, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x22, 0x81, 0x01, 0x0a, 0x19, 0x5a, 0x6c, 0x74, + 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0x89, 0x01, 0x0a, - 0x15, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, - 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x63, - 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, - 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, - 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x54, - 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, - 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0xbc, 0x02, 0x0a, 0x10, 0x5a, 0x6c, 0x74, - 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, - 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, - 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, - 0x1e, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x12, - 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, - 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, - 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x28, 0x0a, - 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x22, 0x81, 0x01, 0x0a, 0x19, 0x5a, 0x6c, 0x74, 0x78, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, - 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0x8d, 0x01, 0x0a, 0x19, - 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, - 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x72, - 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x6d, - 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, - 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0xd2, 0x02, 0x0a, 0x14, - 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, - 0x65, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, - 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, - 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x53, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, - 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, - 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, - 0x74, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x72, - 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x20, - 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x69, - 0x66, 0x79, 0x55, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x74, - 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x32, 0xa0, 0x07, 0x0a, 0x08, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x49, 0x0a, - 0x11, 0x7a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, - 0x67, 0x65, 0x12, 0x1e, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x5a, 0x6c, - 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x52, - 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x44, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x12, 0x62, 0x0a, 0x16, 0x7a, 0x6c, 0x74, 0x78, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x12, 0x23, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x5a, 0x6c, - 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x23, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, - 0x61, 0x72, 0x67, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0d, - 0x7a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x12, 0x1a, 0x2e, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, - 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x66, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x12, - 0x56, 0x0a, 0x12, 0x7a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, - 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0x8d, 0x01, 0x0a, + 0x19, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, + 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, + 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, + 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x22, 0xd2, 0x02, 0x0a, + 0x14, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, + 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x63, 0x68, + 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x53, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x54, 0x72, + 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, + 0x54, 0x72, 0x61, 0x64, 0x65, 0x4e, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, + 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x72, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x74, + 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x32, 0xa0, 0x07, 0x0a, 0x08, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x49, + 0x0a, 0x11, 0x7a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, + 0x72, 0x67, 0x65, 0x12, 0x1e, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x5a, + 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x12, 0x62, 0x0a, 0x16, 0x7a, 0x6c, 0x74, + 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x12, 0x23, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x5a, + 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x23, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x65, 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x63, + 0x68, 0x61, 0x72, 0x67, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x12, 0x41, 0x0a, + 0x0d, 0x7a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x12, 0x1a, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, + 0x12, 0x56, 0x0a, 0x12, 0x7a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, + 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x0c, 0x7a, 0x6c, 0x74, 0x78, 0x4f, - 0x72, 0x64, 0x65, 0x72, 0x53, 0x6d, 0x73, 0x12, 0x19, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x6d, 0x73, 0x52, - 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x5a, 0x6c, - 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x12, 0x47, 0x0a, - 0x10, 0x7a, 0x6c, 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x14, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x13, 0x7a, 0x6c, 0x74, 0x78, 0x52, 0x65, - 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x14, 0x2e, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x52, 0x65, 0x71, 0x1a, 0x20, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x5a, - 0x6c, 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x52, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x7a, 0x6c, 0x74, 0x78, 0x52, 0x73, 0x4d, - 0x69, 0x58, 0x75, 0x65, 0x12, 0x1a, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, - 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, - 0x1a, 0x1a, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x52, 0x73, 0x43, 0x6f, - 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x12, 0x47, 0x0a, 0x0d, - 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x1a, 0x2e, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, - 0x65, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x65, - 0x6e, 0x64, 0x52, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x10, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, - 0x65, 0x79, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x12, 0x1d, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x0c, 0x7a, 0x6c, 0x74, 0x78, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x6d, 0x73, 0x12, 0x19, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x65, 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x6d, 0x73, + 0x52, 0x65, 0x71, 0x1a, 0x19, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x5a, + 0x6c, 0x74, 0x78, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x12, 0x47, + 0x0a, 0x10, 0x7a, 0x6c, 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x14, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x44, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x65, 0x72, 0x2e, 0x5a, 0x6c, 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x13, 0x7a, 0x6c, 0x74, 0x78, 0x52, + 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x14, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x52, 0x65, 0x71, 0x1a, 0x20, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, + 0x5a, 0x6c, 0x74, 0x78, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x74, 0x52, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x7a, 0x6c, 0x74, 0x78, 0x52, 0x73, + 0x4d, 0x69, 0x58, 0x75, 0x65, 0x12, 0x1a, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, + 0x2e, 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x1a, 0x1a, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x52, 0x73, 0x43, + 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x12, 0x47, 0x0a, + 0x0d, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x1a, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x53, + 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x10, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x12, 0x1d, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x44, + 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x44, 0x69, - 0x73, 0x63, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, - 0x63, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0b, 0x6d, 0x61, 0x72, 0x6b, 0x65, - 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x18, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, - 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, - 0x1a, 0x18, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, - 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x12, 0x47, 0x0a, 0x0d, 0x72, 0x73, - 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x1a, 0x2e, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x2e, 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, - 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x63, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0b, 0x6d, 0x61, 0x72, 0x6b, + 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x18, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, + 0x71, 0x1a, 0x18, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x4d, 0x61, 0x72, + 0x6b, 0x65, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x12, 0x47, 0x0a, 0x0d, 0x72, + 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x1a, 0x2e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2e, 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x65, 0x72, 0x2e, 0x52, 0x73, 0x43, 0x6f, 0x75, 0x70, 0x6f, 0x6e, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/untils/request/request.go b/untils/request/request.go new file mode 100644 index 0000000..ffe542f --- /dev/null +++ b/untils/request/request.go @@ -0,0 +1,130 @@ +package request + +import ( + "encoding/json" + "io" + "net/http" + "net/url" + "strings" + "time" +) + +// 请求结构体 +type Request struct { + Method string `json:"method"` // 请求方法 + Url string `json:"url"` // 请求url + Params map[string]string `json:"params"` // Query参数 + Headers map[string]string `json:"headers"` // 请求头 + Cookies map[string]string `json:"cookies"` // todo 处理 Cookies + Data map[string]string `json:"data"` // 表单格式请求数据 + Json map[string]string `json:"json"` // JSON格式请求数据 todo 多层 嵌套 + Files map[string]string `json:"files"` // todo 处理 Files + Raw string `json:"raw"` // 原始请求数据 + JsonByte []byte `json:"json_raw"` // JSON格式请求数据 todo 多层 嵌套 +} + +// 响应结构体 +type Response struct { + StatusCode int `json:"status_code"` // 状态码 + Reason string `json:"reason"` // 状态码说明 + Elapsed float64 `json:"elapsed"` // 请求耗时(秒) + Content []byte `json:"content"` // 响应二进制内容 + Text string `json:"text"` // 响应文本 + Headers map[string]string `json:"headers"` // 响应头 + Cookies map[string]string `json:"cookies"` // todo 添加响应Cookies + Request *Request `json:"request"` // 原始请求 +} + +// 处理请求方法 +func (r *Request) getMethod() string { + return strings.ToUpper(r.Method) // 必须转为全部大写 +} + +// 组装URL +func (r *Request) getUrl() string { + if r.Params != nil { + urlValues := url.Values{} + Url, _ := url.Parse(r.Url) // todo 处理err + for key, value := range r.Params { + urlValues.Set(key, value) + } + Url.RawQuery = urlValues.Encode() + return Url.String() + } + return r.Url +} + +// 组装请求数据 +func (r *Request) getData() io.Reader { + var reqBody string + if r.Headers == nil { + r.Headers = make(map[string]string, 1) + } + if r.Raw != "" { + reqBody = r.Raw + } else if r.Data != nil { + urlValues := url.Values{} + for key, value := range r.Data { + urlValues.Add(key, value) + } + reqBody = urlValues.Encode() + r.Headers["Content-Type"] = "application/x-www-form-urlencoded" + } else if r.Json != nil { + bytesData, _ := json.Marshal(r.Json) + reqBody = string(bytesData) + r.Headers["Content-Type"] = "application/json" + } else if r.JsonByte != nil { + reqBody = string(r.JsonByte) + r.Headers["Content-Type"] = "application/json" + } + return strings.NewReader(reqBody) +} + +// 添加请求头-需要在getData后使用 +func (r *Request) addHeaders(req *http.Request) { + if r.Headers != nil { + for key, value := range r.Headers { + req.Header.Add(key, value) + } + } +} + +// 准备请求 +func (r *Request) prepare() *http.Request { + Method := r.getMethod() + Url := r.getUrl() + Data := r.getData() + req, _ := http.NewRequest(Method, Url, Data) + r.addHeaders(req) + return req +} + +// 组装响应对象 +func (r *Request) packResponse(res *http.Response, elapsed float64) Response { + var resp Response + resBody, _ := io.ReadAll(res.Body) + resp.Content = resBody + resp.Text = string(resBody) + resp.StatusCode = res.StatusCode + resp.Reason = strings.Split(res.Status, " ")[1] + resp.Elapsed = elapsed + resp.Headers = map[string]string{} + for key, value := range res.Header { + resp.Headers[key] = strings.Join(value, ";") + } + return resp +} + +// 发送请求 +func (r *Request) Send() (Response, error) { + req := r.prepare() + client := &http.Client{} + start := time.Now() + res, err := client.Do(req) + if err != nil { + return Response{}, err + } + defer res.Body.Close() + elapsed := time.Since(start).Seconds() + return r.packResponse(res, elapsed), nil +} diff --git a/untils/request/test/wxbiz_test.go b/untils/request/test/wxbiz_test.go new file mode 100644 index 0000000..3d85062 --- /dev/null +++ b/untils/request/test/wxbiz_test.go @@ -0,0 +1,83 @@ +package test + +import ( + "fmt" + "testing" + "trasfer_middleware/until/request" +) + +// 发送GET 请求 +func TestGet(t *testing.T) { + r := request.Request{ + Method: "GET", + Url: "https://httpbin.org/get?name=张三&age=12", + Headers: map[string]string{"Cookie": "abc", "Token": "123"}} + resp, _ := r.Send() + fmt.Printf("状态码: %d\n", resp.StatusCode) + fmt.Printf("原因: %s\n", resp.Reason) + fmt.Printf("响应时间: %f秒\n", resp.Elapsed) + fmt.Printf("响应文本: %s\n", resp.Text) +} + +// 发送GET 带单独Query参数请求 +func TestWAccessToken(t *testing.T) { + appid := "wx381e6a04ab7f69b6" + secret := "16f6152c216c07fdff4c0ecaf1a173ed" + r := request.Request{ + Method: "GET", + Url: "https://api.weixin.qq.com/cgi-bin/token", + + Params: map[string]string{"grant_type": "client_credential", "appid": appid, "secret": secret}, + } + resp, err := r.Send() + if err != nil { + fmt.Println(err) + return + } + fmt.Printf("状态码: %d\n", resp.StatusCode) + fmt.Printf("原因: %s\n", resp.Reason) + fmt.Printf("响应时间: %f秒\n", resp.Elapsed) + fmt.Printf("响应文本: %s\n", resp.Text) +} + +func TestDtalkBlackBard(t *testing.T) { + + r := request.Request{ + Method: "POST", + Url: "https://httpbin.org/post", + Data: map[string]string{"name": "张三", "age": "12"}, + Headers: map[string]string{"Cookie": "abc", "Token": "123"}} + resp, _ := r.Send() + fmt.Printf("状态码: %d\n", resp.StatusCode) + fmt.Printf("原因: %s\n", resp.Reason) + fmt.Printf("响应时间: %f秒\n", resp.Elapsed) + fmt.Printf("响应文本: %s\n", resp.Text) +} + +// 发送POST 表单请求 +func TestPostForm(t *testing.T) { + r := request.Request{ + Method: "POST", + Url: "https://httpbin.org/post", + Data: map[string]string{"name": "张三", "age": "12"}, + Headers: map[string]string{"Cookie": "abc", "Token": "123"}} + resp, _ := r.Send() + fmt.Printf("状态码: %d\n", resp.StatusCode) + fmt.Printf("原因: %s\n", resp.Reason) + fmt.Printf("响应时间: %f秒\n", resp.Elapsed) + fmt.Printf("响应文本: %s\n", resp.Text) +} + +// 发送POST JSON请求 +func TestPostJson(t *testing.T) { + r := request.Request{ + Method: "POST", + Url: "https://httpbin.org/post", + Json: map[string]string{"name": "张三", "age": "12"}, + Headers: map[string]string{"Cookie": "abc", "Token": "123"}} + resp, _ := r.Send() + fmt.Printf("状态码: %d\n", resp.StatusCode) + fmt.Printf("原因: %s\n", resp.Reason) + fmt.Printf("响应时间: %f秒\n", resp.Elapsed) + fmt.Printf("响应文本: %s\n", resp.Text) +}