From 91b47cb5e6da807f24dfaa72aa46ca3db3cd6c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Toledano?= Date: Mon, 30 Sep 2024 15:52:18 +0200 Subject: [PATCH 01/10] test: e2e/client to system tests (#21981) --- .../client/grpc/cmtservice/service_test.go | 347 ------------------ tests/systemtests/cometbft_client_test.go | 330 +++++++++++++++++ tests/systemtests/go.mod | 3 +- tests/systemtests/go.sum | 2 + tests/systemtests/rpc_client.go | 80 ++++ 5 files changed, 414 insertions(+), 348 deletions(-) delete mode 100644 tests/e2e/client/grpc/cmtservice/service_test.go create mode 100644 tests/systemtests/cometbft_client_test.go diff --git a/tests/e2e/client/grpc/cmtservice/service_test.go b/tests/e2e/client/grpc/cmtservice/service_test.go deleted file mode 100644 index e4177a11edfb..000000000000 --- a/tests/e2e/client/grpc/cmtservice/service_test.go +++ /dev/null @@ -1,347 +0,0 @@ -//go:build e2e -// +build e2e - -package cmtservice_test - -import ( - "context" - "fmt" - "testing" - - "github.com/stretchr/testify/suite" - - "cosmossdk.io/simapp" - _ "cosmossdk.io/x/gov" - - "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/network" - qtypes "github.com/cosmos/cosmos-sdk/types/query" - "github.com/cosmos/cosmos-sdk/version" -) - -type E2ETestSuite struct { - suite.Suite - - cfg network.Config - network network.NetworkI - queryClient cmtservice.ServiceClient -} - -func TestE2ETestSuite(t *testing.T) { - suite.Run(t, new(E2ETestSuite)) -} - -func (s *E2ETestSuite) SetupSuite() { - s.T().Log("setting up e2e test suite") - - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - s.cfg = cfg - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) - - s.Require().NoError(s.network.WaitForNextBlock()) - - s.queryClient = cmtservice.NewServiceClient(s.network.GetValidators()[0].GetClientCtx()) -} - -func (s *E2ETestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite") - s.network.Cleanup() -} - -func (s *E2ETestSuite) TestQueryNodeInfo() { - val := s.network.GetValidators()[0] - - res, err := s.queryClient.GetNodeInfo(context.Background(), &cmtservice.GetNodeInfoRequest{}) - s.Require().NoError(err) - s.Require().Equal(res.ApplicationVersion.AppName, version.NewInfo().AppName) - - restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/node_info", val.GetAPIAddress())) - s.Require().NoError(err) - var getInfoRes cmtservice.GetNodeInfoResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(restRes, &getInfoRes)) - s.Require().Equal(getInfoRes.ApplicationVersion.AppName, version.NewInfo().AppName) -} - -func (s *E2ETestSuite) TestQuerySyncing() { - val := s.network.GetValidators()[0] - - _, err := s.queryClient.GetSyncing(context.Background(), &cmtservice.GetSyncingRequest{}) - s.Require().NoError(err) - - restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/syncing", val.GetAPIAddress())) - s.Require().NoError(err) - var syncingRes cmtservice.GetSyncingResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(restRes, &syncingRes)) -} - -func (s *E2ETestSuite) TestQueryLatestBlock() { - val := s.network.GetValidators()[0] - - _, err := s.queryClient.GetLatestBlock(context.Background(), &cmtservice.GetLatestBlockRequest{}) - s.Require().NoError(err) - - restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/latest", val.GetAPIAddress())) - s.Require().NoError(err) - var blockInfoRes cmtservice.GetLatestBlockResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(restRes, &blockInfoRes)) - s.Require().Contains(blockInfoRes.SdkBlock.Header.ProposerAddress, "cosmosvalcons") -} - -func (s *E2ETestSuite) TestQueryBlockByHeight() { - val := s.network.GetValidators()[0] - _, err := s.queryClient.GetBlockByHeight(context.Background(), &cmtservice.GetBlockByHeightRequest{Height: 1}) - s.Require().NoError(err) - - restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/%d", val.GetAPIAddress(), 1)) - s.Require().NoError(err) - var blockInfoRes cmtservice.GetBlockByHeightResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(restRes, &blockInfoRes)) - s.Require().Contains(blockInfoRes.SdkBlock.Header.ProposerAddress, "cosmosvalcons") -} - -func (s *E2ETestSuite) TestQueryLatestValidatorSet() { - val := s.network.GetValidators()[0] - - // nil pagination - res, err := s.queryClient.GetLatestValidatorSet(context.Background(), &cmtservice.GetLatestValidatorSetRequest{ - Pagination: nil, - }) - s.Require().NoError(err) - s.Require().Equal(1, len(res.Validators)) - content, ok := res.Validators[0].PubKey.GetCachedValue().(cryptotypes.PubKey) - s.Require().Equal(true, ok) - s.Require().Equal(content, val.GetPubKey()) - - // with pagination - _, err = s.queryClient.GetLatestValidatorSet(context.Background(), &cmtservice.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{ - Offset: 0, - Limit: 10, - }}) - s.Require().NoError(err) - - // rest request without pagination - _, err = testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest", val.GetAPIAddress())) - s.Require().NoError(err) - - // rest request with pagination - restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=%d&pagination.limit=%d", val.GetAPIAddress(), 0, 1)) - s.Require().NoError(err) - var validatorSetRes cmtservice.GetLatestValidatorSetResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(restRes, &validatorSetRes)) - s.Require().Equal(1, len(validatorSetRes.Validators)) - anyPub, err := codectypes.NewAnyWithValue(val.GetPubKey()) - s.Require().NoError(err) - s.Require().Equal(validatorSetRes.Validators[0].PubKey, anyPub) -} - -func (s *E2ETestSuite) TestLatestValidatorSet_GRPC() { - vals := s.network.GetValidators() - testCases := []struct { - name string - req *cmtservice.GetLatestValidatorSetRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "cannot be nil"}, - {"no pagination", &cmtservice.GetLatestValidatorSetRequest{}, false, ""}, - {"with pagination", &cmtservice.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{Offset: 0, Limit: uint64(len(vals))}}, false, ""}, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - grpcRes, err := s.queryClient.GetLatestValidatorSet(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - } else { - s.Require().NoError(err) - s.Require().Len(grpcRes.Validators, len(vals)) - s.Require().Equal(grpcRes.Pagination.Total, uint64(len(vals))) - content, ok := grpcRes.Validators[0].PubKey.GetCachedValue().(cryptotypes.PubKey) - s.Require().Equal(true, ok) - s.Require().Equal(content, vals[0].GetPubKey()) - } - }) - } -} - -func (s *E2ETestSuite) TestLatestValidatorSet_GRPCGateway() { - vals := s.network.GetValidators() - testCases := []struct { - name string - url string - expErr bool - expErrMsg string - }{ - {"no pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest", vals[0].GetAPIAddress()), false, ""}, - {"pagination invalid fields", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=-1&pagination.limit=-2", vals[0].GetAPIAddress()), true, "strconv.ParseUint"}, - {"with pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=0&pagination.limit=2", vals[0].GetAPIAddress()), false, ""}, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := testutil.GetRequest(tc.url) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result cmtservice.GetLatestValidatorSetResponse - err = vals[0].GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - s.Require().Equal(uint64(len(vals)), result.Pagination.Total) - anyPub, err := codectypes.NewAnyWithValue(vals[0].GetPubKey()) - s.Require().NoError(err) - s.Require().Equal(result.Validators[0].PubKey, anyPub) - } - }) - } -} - -func (s *E2ETestSuite) TestValidatorSetByHeight_GRPC() { - vals := s.network.GetValidators() - testCases := []struct { - name string - req *cmtservice.GetValidatorSetByHeightRequest - expErr bool - expErrMsg string - }{ - {"nil request", nil, true, "request cannot be nil"}, - {"empty request", &cmtservice.GetValidatorSetByHeightRequest{}, true, "height must be greater than 0"}, - {"no pagination", &cmtservice.GetValidatorSetByHeightRequest{Height: 1}, false, ""}, - {"with pagination", &cmtservice.GetValidatorSetByHeightRequest{Height: 1, Pagination: &qtypes.PageRequest{Offset: 0, Limit: 1}}, false, ""}, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - grpcRes, err := s.queryClient.GetValidatorSetByHeight(context.Background(), tc.req) - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.expErrMsg) - } else { - s.Require().NoError(err) - s.Require().Len(grpcRes.Validators, len(vals)) - s.Require().Equal(grpcRes.Pagination.Total, uint64(len(vals))) - } - }) - } -} - -func (s *E2ETestSuite) TestValidatorSetByHeight_GRPCGateway() { - vals := s.network.GetValidators() - testCases := []struct { - name string - url string - expErr bool - expErrMsg string - }{ - {"invalid height", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d", vals[0].GetAPIAddress(), -1), true, "height must be greater than 0"}, - {"no pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d", vals[0].GetAPIAddress(), 1), false, ""}, - {"pagination invalid fields", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d?pagination.offset=-1&pagination.limit=-2", vals[0].GetAPIAddress(), 1), true, "strconv.ParseUint"}, - {"with pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d?pagination.offset=0&pagination.limit=2", vals[0].GetAPIAddress(), 1), false, ""}, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := testutil.GetRequest(tc.url) - s.Require().NoError(err) - if tc.expErr { - s.Require().Contains(string(res), tc.expErrMsg) - } else { - var result cmtservice.GetValidatorSetByHeightResponse - err = vals[0].GetClientCtx().Codec.UnmarshalJSON(res, &result) - s.Require().NoError(err) - s.Require().Equal(uint64(len(vals)), result.Pagination.Total) - } - }) - } -} - -func (s *E2ETestSuite) TestABCIQuery() { - testCases := []struct { - name string - req *cmtservice.ABCIQueryRequest - expectErr bool - expectedCode uint32 - validQuery bool - }{ - { - name: "valid request with proof", - req: &cmtservice.ABCIQueryRequest{ - Path: "/store/gov/key", - Data: []byte{0x03}, - Prove: true, - }, - validQuery: true, - }, - { - name: "valid request without proof", - req: &cmtservice.ABCIQueryRequest{ - Path: "/store/gov/key", - Data: []byte{0x03}, - Prove: false, - }, - validQuery: true, - }, - { - name: "request with invalid path", - req: &cmtservice.ABCIQueryRequest{ - Path: "/foo/bar", - Data: []byte{0x03}, - }, - expectErr: true, - }, - { - name: "request with invalid path recursive", - req: &cmtservice.ABCIQueryRequest{ - Path: "/cosmos.base.tendermint.v1beta1.Service/ABCIQuery", - Data: s.cfg.Codec.MustMarshal(&cmtservice.ABCIQueryRequest{ - Path: "/cosmos.base.tendermint.v1beta1.Service/ABCIQuery", - }), - }, - expectErr: true, - }, - { - name: "request with invalid broadcast tx path", - req: &cmtservice.ABCIQueryRequest{ - Path: "/cosmos.tx.v1beta1.Service/BroadcastTx", - Data: []byte{0x00}, - }, - expectErr: true, - }, - { - name: "request with invalid data", - req: &cmtservice.ABCIQueryRequest{ - Path: "/store/gov/key", - Data: []byte{0x0044, 0x00}, - }, - validQuery: false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - res, err := s.queryClient.ABCIQuery(context.Background(), tc.req) - if tc.expectErr { - s.Require().Error(err) - s.Require().Nil(res) - } else { - s.Require().NoError(err) - s.Require().NotNil(res) - s.Require().Equal(res.Code, tc.expectedCode) - } - - if tc.validQuery { - s.Require().Greater(res.Height, int64(0)) - s.Require().Greater(len(res.Key), 0, "expected non-empty key") - s.Require().Greater(len(res.Value), 0, "expected non-empty value") - } - - if tc.req.Prove { - s.Require().Greater(len(res.ProofOps.Ops), 0, "expected proofs") - } - }) - } -} diff --git a/tests/systemtests/cometbft_client_test.go b/tests/systemtests/cometbft_client_test.go new file mode 100644 index 000000000000..e031ae0c8f55 --- /dev/null +++ b/tests/systemtests/cometbft_client_test.go @@ -0,0 +1,330 @@ +//go:build system_test + +package systemtests + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/tidwall/gjson" + + "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/testutil" + qtypes "github.com/cosmos/cosmos-sdk/types/query" +) + +func TestQueryNodeInfo(t *testing.T) { + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + sut.ResetChain(t) + sut.StartChain(t) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + res, err := qc.GetNodeInfo(context.Background(), &cmtservice.GetNodeInfoRequest{}) + assert.NoError(t, err) + + v := NewCLIWrapper(t, sut, true).Version() + assert.Equal(t, res.ApplicationVersion.Version, v) + + // TODO: we should be adding a way to distinguish a v2. Eventually we should skip some v2 system depending on the consensus engine we want to test + restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/node_info", baseurl)) + assert.NoError(t, err) + assert.Equal(t, gjson.GetBytes(restRes, "application_version.version").String(), res.ApplicationVersion.Version) +} + +func TestQuerySyncing(t *testing.T) { + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + sut.ResetChain(t) + sut.StartChain(t) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + res, err := qc.GetSyncing(context.Background(), &cmtservice.GetSyncingRequest{}) + assert.NoError(t, err) + + restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/syncing", baseurl)) + assert.NoError(t, err) + assert.Equal(t, gjson.GetBytes(restRes, "syncing").Bool(), res.Syncing) +} + +func TestQueryLatestBlock(t *testing.T) { + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + sut.ResetChain(t) + sut.StartChain(t) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + res, err := qc.GetLatestBlock(context.Background(), &cmtservice.GetLatestBlockRequest{}) + assert.NoError(t, err) + assert.Contains(t, res.SdkBlock.Header.ProposerAddress, "cosmosvalcons") + + _, err = testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/latest", baseurl)) + assert.NoError(t, err) +} + +func TestQueryBlockByHeight(t *testing.T) { + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + sut.ResetChain(t) + sut.StartChain(t) + + sut.AwaitNBlocks(t, 2, time.Second*25) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + res, err := qc.GetBlockByHeight(context.Background(), &cmtservice.GetBlockByHeightRequest{Height: 2}) + assert.NoError(t, err) + assert.Equal(t, res.SdkBlock.Header.Height, int64(2)) + assert.Contains(t, res.SdkBlock.Header.ProposerAddress, "cosmosvalcons") + + restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/blocks/%d", baseurl, 2)) + assert.NoError(t, err) + assert.Equal(t, gjson.GetBytes(restRes, "sdk_block.header.height").Int(), int64(2)) + assert.Contains(t, gjson.GetBytes(restRes, "sdk_block.header.proposer_address").String(), "cosmosvalcons") +} + +func TestQueryLatestValidatorSet(t *testing.T) { + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + sut.ResetChain(t) + sut.StartChain(t) + + vals := sut.RPCClient(t).Validators() + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + res, err := qc.GetLatestValidatorSet(context.Background(), &cmtservice.GetLatestValidatorSetRequest{ + Pagination: nil, + }) + assert.NoError(t, err) + assert.Equal(t, len(res.Validators), len(vals)) + + // with pagination + res, err = qc.GetLatestValidatorSet(context.Background(), &cmtservice.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{ + Offset: 0, + Limit: 2, + }}) + assert.NoError(t, err) + assert.Equal(t, len(res.Validators), 2) + + restRes, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=%d&pagination.limit=%d", baseurl, 0, 2)) + assert.NoError(t, err) + assert.Equal(t, len(gjson.GetBytes(restRes, "validators").Array()), 2) +} + +func TestLatestValidatorSet(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + vals := sut.RPCClient(t).Validators() + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + testCases := []struct { + name string + req *cmtservice.GetLatestValidatorSetRequest + expErr bool + expErrMsg string + }{ + {"nil request", nil, true, "cannot be nil"}, + {"no pagination", &cmtservice.GetLatestValidatorSetRequest{}, false, ""}, + {"with pagination", &cmtservice.GetLatestValidatorSetRequest{Pagination: &qtypes.PageRequest{Offset: 0, Limit: uint64(len(vals))}}, false, ""}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := qc.GetLatestValidatorSet(context.Background(), tc.req) + if tc.expErr { + assert.Error(t, err) + assert.Contains(t, err.Error(), tc.expErrMsg) + } else { + assert.NoError(t, err) + assert.Equal(t, len(res.Validators), len(vals)) + content, ok := res.Validators[0].PubKey.GetCachedValue().(cryptotypes.PubKey) + assert.True(t, ok) + assert.Equal(t, content.Address(), vals[0].PubKey.Address()) + } + }) + } +} +func TestLatestValidatorSet_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + + vals := sut.RPCClient(t).Validators() + + testCases := []struct { + name string + url string + expErr bool + expErrMsg string + }{ + {"no pagination", "/cosmos/base/tendermint/v1beta1/validatorsets/latest", false, ""}, + {"pagination invalid fields", "/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=-1&pagination.limit=-2", true, "strconv.ParseUint"}, + {"with pagination", "/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=0&pagination.limit=2", false, ""}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rsp, err := testutil.GetRequest(fmt.Sprintf("%s%s", baseurl, tc.url)) + assert.NoError(t, err) + if tc.expErr { + errMsg := gjson.GetBytes(rsp, "message").String() + assert.Contains(t, errMsg, tc.expErrMsg) + } else { + assert.Equal(t, len(vals), int(gjson.GetBytes(rsp, "pagination.total").Int())) + } + }) + } +} + +func TestValidatorSetByHeight(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + vals := sut.RPCClient(t).Validators() + + testCases := []struct { + name string + req *cmtservice.GetValidatorSetByHeightRequest + expErr bool + expErrMsg string + }{ + {"nil request", nil, true, "request cannot be nil"}, + {"empty request", &cmtservice.GetValidatorSetByHeightRequest{}, true, "height must be greater than 0"}, + {"no pagination", &cmtservice.GetValidatorSetByHeightRequest{Height: 1}, false, ""}, + {"with pagination", &cmtservice.GetValidatorSetByHeightRequest{Height: 1, Pagination: &qtypes.PageRequest{Offset: 0, Limit: uint64(len(vals))}}, false, ""}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := qc.GetValidatorSetByHeight(context.Background(), tc.req) + if tc.expErr { + assert.Error(t, err) + assert.Contains(t, err.Error(), tc.expErrMsg) + } else { + assert.NoError(t, err) + assert.Equal(t, len(res.Validators), len(vals)) + } + }) + } +} + +func TestValidatorSetByHeight_GRPCGateway(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + vals := sut.RPCClient(t).Validators() + + baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + + block := sut.AwaitNextBlock(t, time.Second*3) + testCases := []struct { + name string + url string + expErr bool + expErrMsg string + }{ + {"invalid height", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d", baseurl, -1), true, "height must be greater than 0"}, + {"no pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d", baseurl, block), false, ""}, + {"pagination invalid fields", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d?pagination.offset=-1&pagination.limit=-2", baseurl, block), true, "strconv.ParseUint"}, + {"with pagination", fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/%d?pagination.limit=2", baseurl, 1), false, ""}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rsp, err := testutil.GetRequest(tc.url) + assert.NoError(t, err) + if tc.expErr { + errMsg := gjson.GetBytes(rsp, "message").String() + assert.Contains(t, errMsg, tc.expErrMsg) + } else { + assert.Equal(t, len(vals), int(gjson.GetBytes(rsp, "pagination.total").Int())) + } + }) + } +} + +func TestABCIQuery(t *testing.T) { + sut.ResetChain(t) + sut.StartChain(t) + + qc := cmtservice.NewServiceClient(sut.RPCClient(t)) + cdc := codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) + testCases := []struct { + name string + req *cmtservice.ABCIQueryRequest + expectErr bool + expectedCode uint32 + validQuery bool + }{ + { + name: "valid request with proof", + req: &cmtservice.ABCIQueryRequest{ + Path: "/store/gov/key", + Data: []byte{0x03}, + Prove: true, + }, + validQuery: true, + }, + { + name: "valid request without proof", + req: &cmtservice.ABCIQueryRequest{ + Path: "/store/gov/key", + Data: []byte{0x03}, + Prove: false, + }, + validQuery: true, + }, + { + name: "request with invalid path", + req: &cmtservice.ABCIQueryRequest{ + Path: "/foo/bar", + Data: []byte{0x03}, + }, + expectErr: true, + }, + { + name: "request with invalid path recursive", + req: &cmtservice.ABCIQueryRequest{ + Path: "/cosmos.base.tendermint.v1beta1.Service/ABCIQuery", + Data: cdc.MustMarshal(&cmtservice.ABCIQueryRequest{ + Path: "/cosmos.base.tendermint.v1beta1.Service/ABCIQuery", + }), + }, + expectErr: true, + }, + { + name: "request with invalid broadcast tx path", + req: &cmtservice.ABCIQueryRequest{ + Path: "/cosmos.tx.v1beta1.Service/BroadcastTx", + Data: []byte{0x00}, + }, + expectErr: true, + }, + { + name: "request with invalid data", + req: &cmtservice.ABCIQueryRequest{ + Path: "/store/gov/key", + Data: []byte{0x0044, 0x00}, + }, + validQuery: false, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res, err := qc.ABCIQuery(context.Background(), tc.req) + if tc.expectErr { + assert.Error(t, err) + assert.Nil(t, res) + } else { + assert.NoError(t, err) + assert.NotNil(t, res) + assert.Equal(t, res.Code, tc.expectedCode) + } + + if tc.validQuery { + assert.Greater(t, res.Height, int64(0)) + assert.Greater(t, len(res.Key), 0) + assert.Greater(t, len(res.Value), 0) + } + }) + } +} diff --git a/tests/systemtests/go.mod b/tests/systemtests/go.mod index 5d4949952111..405d9269bf1a 100644 --- a/tests/systemtests/go.mod +++ b/tests/systemtests/go.mod @@ -20,12 +20,13 @@ require ( github.com/stretchr/testify v1.9.0 github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/grpc v1.67.0 // indirect + google.golang.org/grpc v1.67.0 ) require ( cosmossdk.io/math v1.3.0 github.com/cometbft/cometbft v0.38.8 + github.com/cometbft/cometbft/api v1.0.0-rc.1 github.com/creachadair/tomledit v0.0.26 github.com/tidwall/gjson v1.14.2 github.com/tidwall/sjson v1.2.5 diff --git a/tests/systemtests/go.sum b/tests/systemtests/go.sum index af10f89276c4..09314ac894cf 100644 --- a/tests/systemtests/go.sum +++ b/tests/systemtests/go.sum @@ -129,6 +129,8 @@ github.com/cometbft/cometbft v0.38.8 h1:XyJ9Cu3xqap6xtNxiemrO8roXZ+KS2Zlu7qQ0w1t github.com/cometbft/cometbft v0.38.8/go.mod h1:xOoGZrtUT+A5izWfHSJgl0gYZUE7lu7Z2XIS1vWG/QQ= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= +github.com/cometbft/cometbft/api v1.0.0-rc.1 h1:GtdXwDGlqwHYs16A4egjwylfYOMYyEacLBrs3Zvpt7g= +github.com/cometbft/cometbft/api v1.0.0-rc.1/go.mod h1:NDFKiBBD8HJC6QQLAoUI99YhsiRZtg2+FJWfk6A6m6o= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= diff --git a/tests/systemtests/rpc_client.go b/tests/systemtests/rpc_client.go index d1acfd780ff4..4714715be600 100644 --- a/tests/systemtests/rpc_client.go +++ b/tests/systemtests/rpc_client.go @@ -2,11 +2,23 @@ package systemtests import ( "context" + "errors" + "reflect" + "strconv" "testing" + abci "github.com/cometbft/cometbft/api/cometbft/abci/v1" + rpcclient "github.com/cometbft/cometbft/rpc/client" client "github.com/cometbft/cometbft/rpc/client/http" cmtypes "github.com/cometbft/cometbft/types" "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" ) // RPCClient is a test helper to interact with a node via the RPC endpoint. @@ -31,3 +43,71 @@ func (r RPCClient) Validators() []*cmtypes.Validator { require.NoError(r.t, err) return v.Validators } + +func (r RPCClient) Invoke(ctx context.Context, method string, req, reply interface{}, opts ...grpc.CallOption) error { + if reflect.ValueOf(req).IsNil() { + return errors.New("request cannot be nil") + } + + ir := types.NewInterfaceRegistry() + cryptocodec.RegisterInterfaces(ir) + cdc := codec.NewProtoCodec(ir).GRPCCodec() + + reqBz, err := cdc.Marshal(req) + if err != nil { + return err + } + + var height int64 + md, _ := metadata.FromOutgoingContext(ctx) + if heights := md.Get(grpctypes.GRPCBlockHeightHeader); len(heights) > 0 { + height, err := strconv.ParseInt(heights[0], 10, 64) + if err != nil { + return err + } + if height < 0 { + return errors.New("height must be greater than or equal to 0") + } + } + + abciReq := abci.QueryRequest{ + Path: method, + Data: reqBz, + Height: height, + } + + abciOpts := rpcclient.ABCIQueryOptions{ + Height: height, + Prove: abciReq.Prove, + } + + result, err := r.client.ABCIQueryWithOptions(ctx, abciReq.Path, abciReq.Data, abciOpts) + if err != nil { + return err + } + + if !result.Response.IsOK() { + return errors.New(result.Response.String()) + } + + err = cdc.Unmarshal(result.Response.Value, reply) + if err != nil { + return err + } + + md = metadata.Pairs(grpctypes.GRPCBlockHeightHeader, strconv.FormatInt(result.Response.Height, 10)) + for _, callOpt := range opts { + header, ok := callOpt.(grpc.HeaderCallOption) + if !ok { + continue + } + + *header.HeaderAddr = md + } + + return types.UnpackInterfaces(reply, ir) +} + +func (r RPCClient) NewStream(ctx context.Context, desc *grpc.StreamDesc, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) { + return nil, errors.New("not implemented") +} From d493145644035668d5e41a6001e2cc85be2f9308 Mon Sep 17 00:00:00 2001 From: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Date: Mon, 30 Sep 2024 21:29:12 +0700 Subject: [PATCH 02/10] test(gov): Migrate e2e to system test (#21927) --- tests/e2e/gov/cli_test.go | 37 --- tests/e2e/gov/deposits.go | 164 -------------- tests/e2e/gov/tx.go | 372 ------------------------------ tests/systemtests/gov_test.go | 411 ++++++++++++++++++++++++++++++++++ tests/systemtests/system.go | 5 + 5 files changed, 416 insertions(+), 573 deletions(-) delete mode 100644 tests/e2e/gov/cli_test.go delete mode 100644 tests/e2e/gov/deposits.go delete mode 100644 tests/e2e/gov/tx.go create mode 100644 tests/systemtests/gov_test.go diff --git a/tests/e2e/gov/cli_test.go b/tests/e2e/gov/cli_test.go deleted file mode 100644 index be8e7afc82e3..000000000000 --- a/tests/e2e/gov/cli_test.go +++ /dev/null @@ -1,37 +0,0 @@ -//go:build e2e -// +build e2e - -package gov - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - "cosmossdk.io/simapp" - v1 "cosmossdk.io/x/gov/types/v1" - - "github.com/cosmos/cosmos-sdk/testutil/network" -) - -func TestE2ETestSuite(t *testing.T) { - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - suite.Run(t, NewE2ETestSuite(cfg)) -} - -func TestDepositTestSuite(t *testing.T) { - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - genesisState := v1.DefaultGenesisState() - maxDepPeriod := time.Duration(20) * time.Second - votingPeriod := time.Duration(8) * time.Second - genesisState.Params.MaxDepositPeriod = &maxDepPeriod - genesisState.Params.VotingPeriod = &votingPeriod - bz, err := cfg.Codec.MarshalJSON(genesisState) - require.NoError(t, err) - cfg.GenesisState["gov"] = bz - suite.Run(t, NewDepositTestSuite(cfg)) -} diff --git a/tests/e2e/gov/deposits.go b/tests/e2e/gov/deposits.go deleted file mode 100644 index b685fa08bc62..000000000000 --- a/tests/e2e/gov/deposits.go +++ /dev/null @@ -1,164 +0,0 @@ -package gov - -import ( - "fmt" - "strconv" - "time" - - "github.com/stretchr/testify/suite" - - "cosmossdk.io/math" - "cosmossdk.io/x/gov/client/cli" - govclitestutil "cosmossdk.io/x/gov/client/testutil" - v1 "cosmossdk.io/x/gov/types/v1" - "cosmossdk.io/x/gov/types/v1beta1" - - "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -type DepositTestSuite struct { - suite.Suite - - cfg network.Config - network network.NetworkI -} - -func NewDepositTestSuite(cfg network.Config) *DepositTestSuite { - return &DepositTestSuite{cfg: cfg} -} - -func (s *DepositTestSuite) SetupSuite() { - s.T().Log("setting up test suite") - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) -} - -func (s *DepositTestSuite) submitProposal(val network.ValidatorI, initialDeposit sdk.Coin, name string) uint64 { - var exactArgs []string - - if !initialDeposit.IsZero() { - exactArgs = append(exactArgs, fmt.Sprintf("--%s=%s", cli.FlagDeposit, initialDeposit.String())) - } - - _, err := govclitestutil.MsgSubmitLegacyProposal( - val.GetClientCtx(), - val.GetAddress().String(), - fmt.Sprintf("Text Proposal %s", name), - "Where is the title!?", - v1beta1.ProposalTypeText, - exactArgs..., - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // query proposals, return the last's id - res, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals", val.GetAPIAddress())) - s.Require().NoError(err) - var proposals v1.QueryProposalsResponse - err = s.cfg.Codec.UnmarshalJSON(res, &proposals) - s.Require().NoError(err) - s.Require().GreaterOrEqual(len(proposals.Proposals), 1) - - return proposals.Proposals[len(proposals.Proposals)-1].Id -} - -func (s *DepositTestSuite) TearDownSuite() { - s.T().Log("tearing down test suite") - s.network.Cleanup() -} - -func (s *DepositTestSuite) TestQueryDepositsWithInitialDeposit() { - val := s.network.GetValidators()[0] - depositAmount := sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens) - - // submit proposal with an initial deposit - id := s.submitProposal(val, depositAmount, "TestQueryDepositsWithInitialDeposit") - proposalID := strconv.FormatUint(id, 10) - - // query deposit - deposit := s.queryDeposit(val, proposalID, false, "") - s.Require().NotNil(deposit) - s.Require().Equal(depositAmount.String(), sdk.Coins(deposit.Deposit.Amount).String()) - - // query deposits - deposits := s.queryDeposits(val, proposalID, false, "") - s.Require().NotNil(deposits) - s.Require().Len(deposits.Deposits, 1) - // verify initial deposit - s.Require().Equal(depositAmount.String(), sdk.Coins(deposits.Deposits[0].Amount).String()) -} - -func (s *DepositTestSuite) TestQueryProposalAfterVotingPeriod() { - val := s.network.GetValidators()[0] - depositAmount := sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens.Sub(math.NewInt(50))) - - // submit proposal with an initial deposit - id := s.submitProposal(val, depositAmount, "TestQueryProposalAfterVotingPeriod") - proposalID := strconv.FormatUint(id, 10) - - resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals", val.GetAPIAddress())) - s.Require().NoError(err) - var proposals v1.QueryProposalsResponse - err = s.cfg.Codec.UnmarshalJSON(resp, &proposals) - s.Require().NoError(err) - s.Require().GreaterOrEqual(len(proposals.Proposals), 1) - - // query proposal - resp, err = testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals/%s", val.GetAPIAddress(), proposalID)) - s.Require().NoError(err) - var proposal v1.QueryProposalResponse - err = s.cfg.Codec.UnmarshalJSON(resp, &proposal) - s.Require().NoError(err) - - // waiting for deposit and voting period to end - time.Sleep(25 * time.Second) - - // query proposal - resp, err = testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals/%s", val.GetAPIAddress(), proposalID)) - s.Require().NoError(err) - s.Require().Contains(string(resp), fmt.Sprintf("proposal %s doesn't exist", proposalID)) - - // query deposits - deposits := s.queryDeposits(val, proposalID, false, "") - s.Require().Len(deposits.Deposits, 0) -} - -func (s *DepositTestSuite) queryDeposits(val network.ValidatorI, proposalID string, exceptErr bool, message string) *v1.QueryDepositsResponse { - s.Require().NoError(s.network.WaitForNextBlock()) - - resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals/%s/deposits", val.GetAPIAddress(), proposalID)) - s.Require().NoError(err) - - if exceptErr { - s.Require().Contains(string(resp), message) - return nil - } - - var depositsRes v1.QueryDepositsResponse - err = val.GetClientCtx().Codec.UnmarshalJSON(resp, &depositsRes) - s.Require().NoError(err) - - return &depositsRes -} - -func (s *DepositTestSuite) queryDeposit(val network.ValidatorI, proposalID string, exceptErr bool, message string) *v1.QueryDepositResponse { - s.Require().NoError(s.network.WaitForNextBlock()) - - resp, err := testutil.GetRequest(fmt.Sprintf("%s/cosmos/gov/v1/proposals/%s/deposits/%s", val.GetAPIAddress(), proposalID, val.GetAddress().String())) - s.Require().NoError(err) - - if exceptErr { - s.Require().Contains(string(resp), message) - return nil - } - - var depositRes v1.QueryDepositResponse - err = val.GetClientCtx().Codec.UnmarshalJSON(resp, &depositRes) - s.Require().NoError(err) - - return &depositRes -} diff --git a/tests/e2e/gov/tx.go b/tests/e2e/gov/tx.go deleted file mode 100644 index 9d6f84ce15aa..000000000000 --- a/tests/e2e/gov/tx.go +++ /dev/null @@ -1,372 +0,0 @@ -package gov - -import ( - "encoding/base64" - "fmt" - - "github.com/cosmos/gogoproto/proto" - "github.com/stretchr/testify/suite" - - "cosmossdk.io/math" - "cosmossdk.io/x/gov/client/cli" - govclitestutil "cosmossdk.io/x/gov/client/testutil" - "cosmossdk.io/x/gov/types" - v1 "cosmossdk.io/x/gov/types/v1" - "cosmossdk.io/x/gov/types/v1beta1" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -) - -type E2ETestSuite struct { - suite.Suite - - cfg network.Config - network network.NetworkI -} - -func NewE2ETestSuite(cfg network.Config) *E2ETestSuite { - return &E2ETestSuite{cfg: cfg} -} - -func (s *E2ETestSuite) SetupSuite() { - s.T().Log("setting up e2e test suite") - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - val := s.network.GetValidators()[0] - clientCtx := val.GetClientCtx() - var resp sdk.TxResponse - - // create a proposal with deposit - out, err := govclitestutil.MsgSubmitLegacyProposal(val.GetClientCtx(), val.GetAddress().String(), - "Text Proposal 1", "Where is the title!?", v1beta1.ProposalTypeText, - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens).String())) - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) - - // vote for proposal - out, err = govclitestutil.MsgVote(val.GetClientCtx(), val.GetAddress().String(), "1", "yes") - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) - - // create a proposal with a small deposit - minimumAcceptedDep := v1.DefaultMinDepositTokens.ToLegacyDec().Mul(v1.DefaultMinDepositRatio).Ceil().TruncateInt() - out, err = govclitestutil.MsgSubmitLegacyProposal(val.GetClientCtx(), val.GetAddress().String(), - "Text Proposal 2", "Where is the title!?", v1beta1.ProposalTypeText, - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, minimumAcceptedDep).String())) - - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) - - // create a proposal3 with deposit - out, err = govclitestutil.MsgSubmitLegacyProposal(val.GetClientCtx(), val.GetAddress().String(), - "Text Proposal 3", "Where is the title!?", v1beta1.ProposalTypeText, - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens).String())) - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) - - // create a proposal4 with deposit to check the cancel proposal cli tx - out, err = govclitestutil.MsgSubmitLegacyProposal(val.GetClientCtx(), val.GetAddress().String(), - "Text Proposal 4", "Where is the title!?", v1beta1.ProposalTypeText, - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, v1.DefaultMinDepositTokens).String())) - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) - - // vote for proposal3 as val - out, err = govclitestutil.MsgVote(val.GetClientCtx(), val.GetAddress().String(), "3", "yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05") - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, 0)) -} - -func (s *E2ETestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite") - s.network.Cleanup() -} - -func (s *E2ETestSuite) TestNewCmdSubmitProposal() { - val := s.network.GetValidators()[0] - - // Create a legacy proposal JSON, make sure it doesn't pass this new CLI - // command. - invalidProp := `{ - "title": "", - "description": "Where is the title!?", - "type": "Text", - "deposit": "-324foocoin" -}` - invalidPropFile := testutil.WriteToNewTempFile(s.T(), invalidProp) - defer invalidPropFile.Close() - - // Create a valid new proposal JSON. - propMetadata := []byte{42} - validProp := fmt.Sprintf(` -{ - "messages": [ - { - "@type": "/cosmos.gov.v1.MsgExecLegacyContent", - "authority": "%s", - "content": { - "@type": "/cosmos.gov.v1beta1.TextProposal", - "title": "My awesome title", - "description": "My awesome description" - } - } - ], - "title": "My awesome title", - "summary": "My awesome description", - "metadata": "%s", - "deposit": "%s" -}`, authtypes.NewModuleAddress(types.ModuleName), base64.StdEncoding.EncodeToString(propMetadata), sdk.NewCoin(s.cfg.BondDenom, math.NewInt(100000))) - validPropFile := testutil.WriteToNewTempFile(s.T(), validProp) - defer validPropFile.Close() - - testCases := []struct { - name string - args []string - expectErr bool - expectedCode uint32 - respType proto.Message - }{ - { - "invalid proposal", - []string{ - invalidPropFile.Name(), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, nil, - }, - { - "valid proposal", - []string{ - validPropFile.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, &sdk.TxResponse{}, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdSubmitProposal() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - txResp := tc.respType.(*sdk.TxResponse) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode)) - } - }) - } -} - -func (s *E2ETestSuite) TestNewCmdSubmitLegacyProposal() { - val := s.network.GetValidators()[0] - invalidProp := `{ - "title": "", - "description": "Where is the title!?", - "type": "Text", - "deposit": "-324foocoin" - }` - invalidPropFile := testutil.WriteToNewTempFile(s.T(), invalidProp) - defer invalidPropFile.Close() - validProp := fmt.Sprintf(`{ - "title": "Text Proposal", - "description": "Hello, World!", - "type": "Text", - "deposit": "%s" - }`, sdk.NewCoin(s.cfg.BondDenom, math.NewInt(154310))) - validPropFile := testutil.WriteToNewTempFile(s.T(), validProp) - defer validPropFile.Close() - - testCases := []struct { - name string - args []string - expectErr bool - expectedCode uint32 - respType proto.Message - }{ - { - "invalid proposal (file)", - []string{ - fmt.Sprintf("--%s=%s", cli.FlagProposal, invalidPropFile.Name()), //nolint:staticcheck // we are intentionally using a deprecated flag here. - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, nil, - }, - { - "invalid proposal", - []string{ - fmt.Sprintf("--%s='Where is the title!?'", cli.FlagDescription), //nolint:staticcheck // we are intentionally using a deprecated flag here. - fmt.Sprintf("--%s=%s", cli.FlagProposalType, v1beta1.ProposalTypeText), //nolint:staticcheck // we are intentionally using a deprecated flag here. - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10000)).String()), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, nil, - }, - { - "valid transaction (file)", - //nolint:staticcheck // we are intentionally using a deprecated flag here. - []string{ - fmt.Sprintf("--%s=%s", cli.FlagProposal, validPropFile.Name()), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, &sdk.TxResponse{}, - }, - { - "valid transaction", - []string{ - fmt.Sprintf("--%s='Text Proposal'", cli.FlagTitle), - fmt.Sprintf("--%s='Where is the title!?'", cli.FlagDescription), //nolint:staticcheck // we are intentionally using a deprecated flag here. - fmt.Sprintf("--%s=%s", cli.FlagProposalType, v1beta1.ProposalTypeText), //nolint:staticcheck // we are intentionally using a deprecated flag here. - fmt.Sprintf("--%s=%s", cli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, math.NewInt(100000)).String()), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, &sdk.TxResponse{}, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdSubmitLegacyProposal() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - txResp := tc.respType.(*sdk.TxResponse) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode)) - } - }) - } -} - -func (s *E2ETestSuite) TestNewCmdWeightedVote() { - val := s.network.GetValidators()[0] - - testCases := []struct { - name string - args []string - expectErr bool - expectedCode uint32 - }{ - { - "invalid vote", - []string{}, - true, 0, - }, - { - "vote for invalid proposal", - []string{ - "10", - "yes", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 3, - }, - { - "valid vote", - []string{ - "1", - "yes", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, - }, - { - "valid vote with metadata", - []string{ - "1", - "yes", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--metadata=%s", "AQ=="), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, - }, - { - "invalid valid split vote string", - []string{ - "1", - "yes/0.6,no/0.3,abstain/0.05,no_with_veto/0.05", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - true, 0, - }, - { - "valid split vote", - []string{ - "1", - "yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - false, 0, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdWeightedVote() - clientCtx := val.GetClientCtx() - var txResp sdk.TxResponse - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode)) - } - }) - } -} diff --git a/tests/systemtests/gov_test.go b/tests/systemtests/gov_test.go new file mode 100644 index 000000000000..73bc7fd96efc --- /dev/null +++ b/tests/systemtests/gov_test.go @@ -0,0 +1,411 @@ +//go:build system_test + +package systemtests + +import ( + "encoding/base64" + "fmt" + "testing" + "time" + + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" +) + +func TestSubmitProposal(t *testing.T) { + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address + valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String() + require.NotEmpty(t, valAddr) + + sut.StartChain(t) + + // get gov module address + resp := cli.CustomQuery("q", "auth", "module-account", "gov") + govAddress := gjson.Get(resp, "account.value.address").String() + + invalidProp := `{ + "title": "", + "description": "Where is the title!?", + "type": "Text", + "deposit": "-324foocoin" +}` + invalidPropFile := testutil.WriteToNewTempFile(t, invalidProp) + defer invalidPropFile.Close() + + // Create a valid new proposal JSON. + propMetadata := []byte{42} + validProp := fmt.Sprintf(` +{ + "messages": [ + { + "@type": "/cosmos.gov.v1.MsgExecLegacyContent", + "authority": "%s", + "content": { + "@type": "/cosmos.gov.v1beta1.TextProposal", + "title": "My awesome title", + "description": "My awesome description" + } + } + ], + "title": "My awesome title", + "summary": "My awesome description", + "metadata": "%s", + "deposit": "%s" +}`, govAddress, base64.StdEncoding.EncodeToString(propMetadata), sdk.NewCoin("stake", math.NewInt(100000))) + validPropFile := testutil.WriteToNewTempFile(t, validProp) + defer validPropFile.Close() + + testCases := []struct { + name string + args []string + expectErr bool + errMsg string + }{ + { + "invalid proposal", + []string{ + "tx", "gov", "submit-proposal", + invalidPropFile.Name(), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + true, + "invalid character in coin string", + }, + { + "valid proposal", + []string{ + "tx", "gov", "submit-proposal", + validPropFile.Name(), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.expectErr { + assertOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { + require.Contains(t, gotOutputs[0], tc.errMsg) + return false + } + + cli.WithRunErrorMatcher(assertOutput).Run(tc.args...) + } else { + rsp := cli.Run(tc.args...) + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + } + }) + } +} + +func TestSubmitLegacyProposal(t *testing.T) { + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address + valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String() + require.NotEmpty(t, valAddr) + + sut.StartChain(t) + + invalidProp := `{ + "title": "", + "description": "Where is the title!?", + "type": "Text", + "deposit": "-324foocoin" + }` + invalidPropFile := testutil.WriteToNewTempFile(t, invalidProp) + defer invalidPropFile.Close() + + validProp := fmt.Sprintf(`{ + "title": "Text Proposal", + "description": "Hello, World!", + "type": "Text", + "deposit": "%s" + }`, sdk.NewCoin("stake", math.NewInt(154310))) + validPropFile := testutil.WriteToNewTempFile(t, validProp) + defer validPropFile.Close() + + testCases := []struct { + name string + args []string + expectErr bool + errMsg string + }{ + { + "invalid proposal (file)", + []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s=%s", "proposal", invalidPropFile.Name()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + true, + "proposal title is required", + }, + { + "invalid proposal", + []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s='Where is the title!?'", "description"), + fmt.Sprintf("--%s=%s", "type", "Text"), + fmt.Sprintf("--%s=%s", "deposit", sdk.NewCoin("stake", math.NewInt(10000)).String()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + true, + "proposal title is required", + }, + { + "valid transaction (file)", + []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s=%s", "proposal", validPropFile.Name()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, + "", + }, + { + "valid transaction", + []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s='Text Proposal'", "title"), + fmt.Sprintf("--%s='Where is the title!?'", "description"), + fmt.Sprintf("--%s=%s", "type", "Text"), + fmt.Sprintf("--%s=%s", "deposit", sdk.NewCoin("stake", math.NewInt(100000)).String()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.expectErr { + assertOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { + fmt.Println("gotOut", gotOutputs) + require.Contains(t, gotOutputs[0], tc.errMsg) + return false + } + + cli.WithRunErrorMatcher(assertOutput).Run(tc.args...) + } else { + rsp := cli.Run(tc.args...) + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + } + }) + } +} + +func TestNewCmdWeightedVote(t *testing.T) { + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address + valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String() + require.NotEmpty(t, valAddr) + + sut.StartChain(t) + + // Submit a new proposal for voting + proposalArgs := []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s='Text Proposal'", "title"), + fmt.Sprintf("--%s='Where is the title!?'", "description"), + fmt.Sprintf("--%s=%s", "type", "Text"), + fmt.Sprintf("--%s=%s", "deposit", sdk.NewCoin("stake", math.NewInt(10_000_000)).String()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String())} + rsp := cli.Run(proposalArgs...) + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + + proposalsResp := cli.CustomQuery("q", "gov", "proposals") + proposals := gjson.Get(proposalsResp, "proposals.#.id").Array() + require.NotEmpty(t, proposals) + + proposal1 := cli.CustomQuery("q", "gov", "proposal", "1") + fmt.Println("first proposal", proposal1) + + testCases := []struct { + name string + args []string + expectErr bool + expectedCode uint32 + broadcasted bool + errMsg string + }{ + { + "vote for invalid proposal", + []string{ + "tx", "gov", "weighted-vote", + "10", + "yes", + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + true, 3, true, + "inactive proposal", + }, + { + "valid vote", + []string{ + "tx", "gov", "weighted-vote", + "1", + "yes", + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, 0, true, + "", + }, + { + "valid vote with metadata", + []string{ + "tx", "gov", "weighted-vote", + "1", + "yes", + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--metadata=%s", "AQ=="), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, 0, true, + "", + }, + { + "invalid valid split vote string", + []string{ + "tx", "gov", "weighted-vote", + "1", + "yes/0.6,no/0.3,abstain/0.05,no_with_veto/0.05", + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + true, 0, false, + "is not a valid vote option", + }, + { + "valid split vote", + []string{ + "tx", "gov", "weighted-vote", + "1", + "yes=0.6,no=0.3,abstain=0.05,no_with_veto=0.05", + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String()), + }, + false, 0, true, + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if !tc.broadcasted { + assertOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { + require.Contains(t, gotOutputs[0], tc.errMsg) + return false + } + cli.WithRunErrorMatcher(assertOutput).Run(tc.args...) + } else { + rsp := cli.Run(tc.args...) + if tc.expectErr { + RequireTxFailure(t, rsp) + } else { + cli.AwaitTxCommitted(rsp) + } + } + }) + } +} + +func TestQueryDeposit(t *testing.T) { + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address + valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String() + require.NotEmpty(t, valAddr) + + sut.StartChain(t) + + // Submit a new proposal for voting + proposalArgs := []string{ + "tx", "gov", "submit-legacy-proposal", + fmt.Sprintf("--%s='Text Proposal'", "title"), + fmt.Sprintf("--%s='Where is the title!?'", "description"), + fmt.Sprintf("--%s=%s", "type", "Text"), + fmt.Sprintf("--%s=%s", "deposit", sdk.NewCoin("stake", math.NewInt(10_000_000)).String()), + fmt.Sprintf("--%s=%s", flags.FlagFrom, valAddr), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10))).String())} + rsp := cli.Run(proposalArgs...) + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + + // Query initial deposit + resp := cli.CustomQuery("q", "gov", "deposit", "1", valAddr) + depositAmount := gjson.Get(resp, "deposit.amount.0.amount").Int() + require.Equal(t, depositAmount, int64(10_000_000)) + + resp = cli.CustomQuery("q", "gov", "deposits", "1") + deposits := gjson.Get(resp, "deposits").Array() + require.Equal(t, len(deposits), 1) + + time.Sleep(time.Second * 8) + resp = cli.CustomQuery("q", "gov", "deposits", "1") + deposits = gjson.Get(resp, "deposits").Array() + require.Equal(t, len(deposits), 0) +} diff --git a/tests/systemtests/system.go b/tests/systemtests/system.go index d76d482b89e2..028645956d85 100644 --- a/tests/systemtests/system.go +++ b/tests/systemtests/system.go @@ -132,6 +132,11 @@ func (s *SystemUnderTest) SetupChain() { if err != nil { panic(fmt.Sprintf("failed set block max gas: %s", err)) } + // Short period for gov + genesisBz, err = sjson.SetRawBytes(genesisBz, "app_state.gov.params.voting_period", []byte(fmt.Sprintf(`"%s"`, "8s"))) + if err != nil { + panic(fmt.Sprintf("failed set block max gas: %s", err)) + } s.withEachNodeHome(func(i int, home string) { if err := saveGenesis(home, genesisBz); err != nil { panic(err) From c44683d49f0581aa39f1f8d993e7a9b20fa8a752 Mon Sep 17 00:00:00 2001 From: "harry m. k." Date: Tue, 1 Oct 2024 13:47:22 +0800 Subject: [PATCH 03/10] chore(contributing): delete link (#21990) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3cac0bfcbdb2..9d1ccdc0caae 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -200,7 +200,7 @@ that you would like early feedback and tagging whoever you would like to receive Codeowners are marked automatically as the reviewers. All PRs require at least two review approvals before they can be merged (one review might be acceptable in -the case of minor changes to [docs](./.github/PULL_REQUEST_TEMPLATE/docs.md) changes that do not affect production code). Each PR template has a reviewers checklist that must be completed before the PR can be merged. Each reviewer is responsible +the case of minor changes to docs changes that do not affect production code). Each PR template has a reviewers checklist that must be completed before the PR can be merged. Each reviewer is responsible for all checked items unless they have indicated otherwise by leaving their handle next to specific items. In addition, use the following review explanations: From 8763d8d99fe164a385dc0ba26f8828c25db7a48e Mon Sep 17 00:00:00 2001 From: Facundo Medica <14063057+facundomedica@users.noreply.github.com> Date: Tue, 1 Oct 2024 09:29:56 +0200 Subject: [PATCH 04/10] chore(x/authz)!: Remove account keeper dependency (#21632) --- simapp/app.go | 2 +- x/authz/CHANGELOG.md | 1 + x/authz/expected_keepers.go | 9 --- x/authz/keeper/genesis.go | 8 +-- x/authz/keeper/genesis_test.go | 21 +++---- x/authz/keeper/grpc_query.go | 12 ++-- x/authz/keeper/grpc_query_test.go | 12 ++-- x/authz/keeper/keeper.go | 23 ++++---- x/authz/keeper/keeper_test.go | 48 ++++++++-------- x/authz/keeper/msg_server.go | 12 ++-- x/authz/keeper/msg_server_test.go | 52 +++++++---------- x/authz/module/abci_test.go | 20 ++----- x/authz/module/depinject.go | 12 ++-- x/authz/testutil/expected_keepers_mocks.go | 66 ---------------------- 14 files changed, 96 insertions(+), 202 deletions(-) diff --git a/simapp/app.go b/simapp/app.go index fd9b8f0efaca..96ae2f04dbae 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -398,7 +398,7 @@ func NewSimApp( app.CircuitKeeper = circuitkeeper.NewKeeper(runtime.NewEnvironment(runtime.NewKVStoreService(keys[circuittypes.StoreKey]), logger.With(log.ModuleKey, "x/circuit")), appCodec, govModuleAddr, app.AuthKeeper.AddressCodec()) app.BaseApp.SetCircuitBreaker(&app.CircuitKeeper) - app.AuthzKeeper = authzkeeper.NewKeeper(runtime.NewEnvironment(runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), logger.With(log.ModuleKey, "x/authz"), runtime.EnvWithMsgRouterService(app.MsgServiceRouter()), runtime.EnvWithQueryRouterService(app.GRPCQueryRouter())), appCodec, app.AuthKeeper) + app.AuthzKeeper = authzkeeper.NewKeeper(runtime.NewEnvironment(runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), logger.With(log.ModuleKey, "x/authz"), runtime.EnvWithMsgRouterService(app.MsgServiceRouter()), runtime.EnvWithQueryRouterService(app.GRPCQueryRouter())), appCodec, signingCtx.AddressCodec()) groupConfig := group.DefaultConfig() /* diff --git a/x/authz/CHANGELOG.md b/x/authz/CHANGELOG.md index 6d3a4ccb1ea2..a898236bcdb1 100644 --- a/x/authz/CHANGELOG.md +++ b/x/authz/CHANGELOG.md @@ -37,6 +37,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes +* [#21632](https://github.com/cosmos/cosmos-sdk/pull/21632) `NewKeeper` now takes `address.Codec` instead of `authKeeper`. * [#21044](https://github.com/cosmos/cosmos-sdk/pull/21044) `k.DispatchActions` returns a slice of byte slices of proto marshaled anys instead of a slice of byte slices of `sdk.Result.Data`. * [#20502](https://github.com/cosmos/cosmos-sdk/pull/20502) `Accept` on the `Authorization` interface now expects the authz environment in the `context.Context`. This is already done when `Accept` is called by `k.DispatchActions`, but should be done manually if `Accept` is called directly. * [#19783](https://github.com/cosmos/cosmos-sdk/pull/19783) Removes the use of Accounts String() method diff --git a/x/authz/expected_keepers.go b/x/authz/expected_keepers.go index fad3b4b74467..b2ee6bd16fbf 100644 --- a/x/authz/expected_keepers.go +++ b/x/authz/expected_keepers.go @@ -3,18 +3,9 @@ package authz import ( "context" - "cosmossdk.io/core/address" - sdk "github.com/cosmos/cosmos-sdk/types" ) -// AccountKeeper defines the expected account keeper (noalias) -type AccountKeeper interface { - AddressCodec() address.Codec - GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI - NewAccountWithAddress(ctx context.Context, addr sdk.AccAddress) sdk.AccountI -} - // BankKeeper defines the expected interface needed to retrieve account balances. type BankKeeper interface { SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins diff --git a/x/authz/keeper/genesis.go b/x/authz/keeper/genesis.go index c669f2aa2622..45762713b61d 100644 --- a/x/authz/keeper/genesis.go +++ b/x/authz/keeper/genesis.go @@ -18,11 +18,11 @@ func (k Keeper) InitGenesis(ctx context.Context, data *authz.GenesisState) error continue } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(entry.Grantee) + grantee, err := k.addrCdc.StringToBytes(entry.Grantee) if err != nil { return err } - granter, err := k.authKeeper.AddressCodec().StringToBytes(entry.Granter) + granter, err := k.addrCdc.StringToBytes(entry.Granter) if err != nil { return err } @@ -44,11 +44,11 @@ func (k Keeper) InitGenesis(ctx context.Context, data *authz.GenesisState) error func (k Keeper) ExportGenesis(ctx context.Context) (*authz.GenesisState, error) { var entries []authz.GrantAuthorization err := k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant authz.Grant) (bool, error) { - granterAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + granterAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return false, err } - granteeAddr, err := k.authKeeper.AddressCodec().BytesToString(grantee) + granteeAddr, err := k.addrCdc.BytesToString(grantee) if err != nil { return false, err } diff --git a/x/authz/keeper/genesis_test.go b/x/authz/keeper/genesis_test.go index 6cc9db972025..53b96a8f94be 100644 --- a/x/authz/keeper/genesis_test.go +++ b/x/authz/keeper/genesis_test.go @@ -4,7 +4,6 @@ import ( "testing" "time" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/suite" "cosmossdk.io/core/header" @@ -14,11 +13,10 @@ import ( storetypes "cosmossdk.io/store/types" "cosmossdk.io/x/authz/keeper" authzmodule "cosmossdk.io/x/authz/module" - authztestutil "cosmossdk.io/x/authz/testutil" bank "cosmossdk.io/x/bank/types" "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/codec/address" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/runtime" @@ -37,11 +35,10 @@ var ( type GenesisTestSuite struct { suite.Suite - ctx sdk.Context - keeper keeper.Keeper - baseApp *baseapp.BaseApp - accountKeeper *authztestutil.MockAccountKeeper - encCfg moduletestutil.TestEncodingConfig + ctx sdk.Context + keeper keeper.Keeper + baseApp *baseapp.BaseApp + encCfg moduletestutil.TestEncodingConfig } func (suite *GenesisTestSuite) SetupTest() { @@ -52,11 +49,6 @@ func (suite *GenesisTestSuite) SetupTest() { suite.encCfg = moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, authzmodule.AppModule{}) - // gomock initializations - ctrl := gomock.NewController(suite.T()) - suite.accountKeeper = authztestutil.NewMockAccountKeeper(ctrl) - suite.accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() - suite.baseApp = baseapp.NewBaseApp( "authz", log.NewNopLogger(), @@ -71,7 +63,8 @@ func (suite *GenesisTestSuite) SetupTest() { msr.SetInterfaceRegistry(suite.encCfg.InterfaceRegistry) env := runtime.NewEnvironment(storeService, coretesting.NewNopLogger(), runtime.EnvWithMsgRouterService(msr)) - suite.keeper = keeper.NewKeeper(env, suite.encCfg.Codec, suite.accountKeeper) + addrCdc := addresscodec.NewBech32Codec("cosmos") + suite.keeper = keeper.NewKeeper(env, suite.encCfg.Codec, addrCdc) } func (suite *GenesisTestSuite) TestImportExportGenesis() { diff --git a/x/authz/keeper/grpc_query.go b/x/authz/keeper/grpc_query.go index 89cb8ac67d65..f3bba8f1aed6 100644 --- a/x/authz/keeper/grpc_query.go +++ b/x/authz/keeper/grpc_query.go @@ -25,12 +25,12 @@ func (k Keeper) Grants(ctx context.Context, req *authz.QueryGrantsRequest) (*aut return nil, status.Errorf(codes.InvalidArgument, "empty request") } - granter, err := k.authKeeper.AddressCodec().StringToBytes(req.Granter) + granter, err := k.addrCdc.StringToBytes(req.Granter) if err != nil { return nil, err } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(req.Grantee) + grantee, err := k.addrCdc.StringToBytes(req.Grantee) if err != nil { return nil, err } @@ -95,7 +95,7 @@ func (k Keeper) GranterGrants(ctx context.Context, req *authz.QueryGranterGrants return nil, status.Errorf(codes.InvalidArgument, "empty request") } - granter, err := k.authKeeper.AddressCodec().StringToBytes(req.Granter) + granter, err := k.addrCdc.StringToBytes(req.Granter) if err != nil { return nil, err } @@ -116,7 +116,7 @@ func (k Keeper) GranterGrants(ctx context.Context, req *authz.QueryGranterGrants grantee := firstAddressFromGrantStoreKey(key) - granteeAddr, err := k.authKeeper.AddressCodec().BytesToString(grantee) + granteeAddr, err := k.addrCdc.BytesToString(grantee) if err != nil { return nil, err } @@ -146,7 +146,7 @@ func (k Keeper) GranteeGrants(ctx context.Context, req *authz.QueryGranteeGrants return nil, status.Errorf(codes.InvalidArgument, "empty request") } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(req.Grantee) + grantee, err := k.addrCdc.StringToBytes(req.Grantee) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func (k Keeper) GranteeGrants(ctx context.Context, req *authz.QueryGranteeGrants return nil, status.Error(codes.Internal, err.Error()) } - granterAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + granterAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return nil, err } diff --git a/x/authz/keeper/grpc_query_test.go b/x/authz/keeper/grpc_query_test.go index b8d5042a96c8..d4239b0f854c 100644 --- a/x/authz/keeper/grpc_query_test.go +++ b/x/authz/keeper/grpc_query_test.go @@ -21,9 +21,9 @@ func (suite *TestSuite) TestGRPCQueryAuthorization() { expAuthorization authz.Authorization ) - addr0, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[0]) + addr0, err := suite.addrCdc.BytesToString(addrs[0]) suite.Require().NoError(err) - addr1, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[1]) + addr1, err := suite.addrCdc.BytesToString(addrs[1]) suite.Require().NoError(err) testCases := []struct { @@ -137,7 +137,7 @@ func (suite *TestSuite) TestGRPCQueryGranterGrants() { require := suite.Require() queryClient, addrs := suite.queryClient, suite.addrs - addr0, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[0]) + addr0, err := suite.addrCdc.BytesToString(addrs[0]) suite.Require().NoError(err) testCases := []struct { @@ -209,9 +209,9 @@ func (suite *TestSuite) TestGRPCQueryGranteeGrants() { require := suite.Require() queryClient, addrs := suite.queryClient, suite.addrs - addr0, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[0]) + addr0, err := suite.addrCdc.BytesToString(addrs[0]) suite.Require().NoError(err) - addr2, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[2]) + addr2, err := suite.addrCdc.BytesToString(addrs[2]) suite.Require().NoError(err) testCases := []struct { @@ -299,7 +299,7 @@ func (suite *TestSuite) createSendAuthorization(grantee, granter sdk.AccAddress) func (suite *TestSuite) createSendAuthorizationWithAllowList(grantee, granter sdk.AccAddress) authz.Authorization { exp := suite.ctx.HeaderInfo().Time.Add(time.Hour) newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100)) - addr, err := suite.accountKeeper.AddressCodec().BytesToString(suite.addrs[5]) + addr, err := suite.addrCdc.BytesToString(suite.addrs[5]) suite.Require().NoError(err) authorization := &banktypes.SendAuthorization{SpendLimit: newCoins, AllowList: []string{addr}} err = suite.authzKeeper.SaveGrant(suite.ctx, grantee, granter, authorization, &exp) diff --git a/x/authz/keeper/keeper.go b/x/authz/keeper/keeper.go index ecfed97ee7cf..087f73aafcf3 100644 --- a/x/authz/keeper/keeper.go +++ b/x/authz/keeper/keeper.go @@ -9,6 +9,7 @@ import ( gogoproto "github.com/cosmos/gogoproto/proto" gogoprotoany "github.com/cosmos/gogoproto/types/any" + "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" corecontext "cosmossdk.io/core/context" errorsmod "cosmossdk.io/errors" @@ -30,16 +31,16 @@ const gasCostPerIteration = uint64(20) type Keeper struct { appmodule.Environment - cdc codec.Codec - authKeeper authz.AccountKeeper + cdc codec.Codec + addrCdc address.Codec } // NewKeeper constructs a message authorization Keeper -func NewKeeper(env appmodule.Environment, cdc codec.Codec, ak authz.AccountKeeper) Keeper { +func NewKeeper(env appmodule.Environment, cdc codec.Codec, addrCdc address.Codec) Keeper { return Keeper{ Environment: env, cdc: cdc, - authKeeper: ak, + addrCdc: addrCdc, } } @@ -206,11 +207,11 @@ func (k Keeper) SaveGrant(ctx context.Context, grantee, granter sdk.AccAddress, return err } - granterAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + granterAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return err } - granteeAddr, err := k.authKeeper.AddressCodec().BytesToString(grantee) + granteeAddr, err := k.addrCdc.BytesToString(grantee) if err != nil { return err } @@ -229,12 +230,12 @@ func (k Keeper) DeleteGrant(ctx context.Context, grantee, granter sdk.AccAddress skey := grantStoreKey(grantee, granter, msgType) grant, found := k.getGrant(ctx, skey) if !found { - granterAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + granterAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return errorsmod.Wrapf(authz.ErrNoAuthorizationFound, "could not convert granter address to string") } - granteeAddr, err := k.authKeeper.AddressCodec().BytesToString(grantee) + granteeAddr, err := k.addrCdc.BytesToString(grantee) if err != nil { return errorsmod.Wrapf(authz.ErrNoAuthorizationFound, "could not convert grantee address to string") @@ -255,11 +256,11 @@ func (k Keeper) DeleteGrant(ctx context.Context, grantee, granter sdk.AccAddress return err } - granterAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + granterAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return err } - granteeAddr, err := k.authKeeper.AddressCodec().BytesToString(grantee) + granteeAddr, err := k.addrCdc.BytesToString(grantee) if err != nil { return err } @@ -291,7 +292,7 @@ func (k Keeper) DeleteAllGrants(ctx context.Context, granter sdk.AccAddress) err } } - grantAddr, err := k.authKeeper.AddressCodec().BytesToString(granter) + grantAddr, err := k.addrCdc.BytesToString(granter) if err != nil { return err } diff --git a/x/authz/keeper/keeper_test.go b/x/authz/keeper/keeper_test.go index dcfd710fc264..f977ffef22fb 100644 --- a/x/authz/keeper/keeper_test.go +++ b/x/authz/keeper/keeper_test.go @@ -9,6 +9,7 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/suite" + "cosmossdk.io/core/address" "cosmossdk.io/core/header" coretesting "cosmossdk.io/core/testing" "cosmossdk.io/log" @@ -20,7 +21,7 @@ import ( banktypes "cosmossdk.io/x/bank/types" "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/codec/address" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" @@ -39,15 +40,15 @@ var ( type TestSuite struct { suite.Suite - ctx sdk.Context - addrs []sdk.AccAddress - authzKeeper authzkeeper.Keeper - accountKeeper *authztestutil.MockAccountKeeper - bankKeeper *authztestutil.MockBankKeeper - baseApp *baseapp.BaseApp - encCfg moduletestutil.TestEncodingConfig - queryClient authz.QueryClient - msgSrvr authz.MsgServer + ctx sdk.Context + addrs []sdk.AccAddress + authzKeeper authzkeeper.Keeper + bankKeeper *authztestutil.MockBankKeeper + baseApp *baseapp.BaseApp + encCfg moduletestutil.TestEncodingConfig + queryClient authz.QueryClient + msgSrvr authz.MsgServer + addrCdc address.Codec } func (s *TestSuite) SetupTest() { @@ -70,16 +71,13 @@ func (s *TestSuite) SetupTest() { // gomock initializations ctrl := gomock.NewController(s.T()) - s.accountKeeper = authztestutil.NewMockAccountKeeper(ctrl) - - s.accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() - s.bankKeeper = authztestutil.NewMockBankKeeper(ctrl) banktypes.RegisterInterfaces(s.encCfg.InterfaceRegistry) banktypes.RegisterMsgServer(s.baseApp.MsgServiceRouter(), s.bankKeeper) env := runtime.NewEnvironment(storeService, coretesting.NewNopLogger(), runtime.EnvWithQueryRouterService(s.baseApp.GRPCQueryRouter()), runtime.EnvWithMsgRouterService(s.baseApp.MsgServiceRouter())) - s.authzKeeper = authzkeeper.NewKeeper(env, s.encCfg.Codec, s.accountKeeper) + s.addrCdc = addresscodec.NewBech32Codec("cosmos") + s.authzKeeper = authzkeeper.NewKeeper(env, s.encCfg.Codec, s.addrCdc) queryHelper := baseapp.NewQueryServerTestHelper(s.ctx, s.encCfg.InterfaceRegistry) authz.RegisterQueryServer(queryHelper, s.authzKeeper) @@ -183,7 +181,7 @@ func (s *TestSuite) TestKeeperIter() { granteeAddr := addrs[1] granter2Addr := addrs[2] e := ctx.HeaderInfo().Time.AddDate(1, 0, 0) - sendAuthz := banktypes.NewSendAuthorization(coins100, nil, s.accountKeeper.AddressCodec()) + sendAuthz := banktypes.NewSendAuthorization(coins100, nil, s.addrCdc) err := s.authzKeeper.SaveGrant(ctx, granteeAddr, granterAddr, sendAuthz, &e) s.Require().NoError(err) @@ -207,7 +205,7 @@ func (s *TestSuite) TestKeeperGranterGrantsIter() { grantee2Addr := addrs[3] grantee3Addr := addrs[4] e := ctx.HeaderInfo().Time.AddDate(1, 0, 0) - sendAuthz := banktypes.NewSendAuthorization(coins100, nil, s.accountKeeper.AddressCodec()) + sendAuthz := banktypes.NewSendAuthorization(coins100, nil, s.addrCdc) err := s.authzKeeper.SaveGrant(ctx, granteeAddr, granterAddr, sendAuthz, &e) s.Require().NoError(err) @@ -238,13 +236,13 @@ func (s *TestSuite) TestDispatchAction() { granterAddr := addrs[0] granteeAddr := addrs[1] - granterStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[0]) + granterStrAddr, err := s.addrCdc.BytesToString(addrs[0]) s.Require().NoError(err) - granteeStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[1]) + granteeStrAddr, err := s.addrCdc.BytesToString(addrs[1]) s.Require().NoError(err) - recipientStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[2]) + recipientStrAddr, err := s.addrCdc.BytesToString(addrs[2]) s.Require().NoError(err) - a := banktypes.NewSendAuthorization(coins100, nil, s.accountKeeper.AddressCodec()) + a := banktypes.NewSendAuthorization(coins100, nil, s.addrCdc) testCases := []struct { name string @@ -402,11 +400,11 @@ func (s *TestSuite) TestDispatchedEvents() { addrs := s.addrs granterAddr := addrs[0] granteeAddr := addrs[1] - granterStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[0]) + granterStrAddr, err := s.addrCdc.BytesToString(addrs[0]) s.Require().NoError(err) - granteeStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[1]) + granteeStrAddr, err := s.addrCdc.BytesToString(addrs[1]) s.Require().NoError(err) - recipientStrAddr, err := s.accountKeeper.AddressCodec().BytesToString(addrs[2]) + recipientStrAddr, err := s.addrCdc.BytesToString(addrs[2]) s.Require().NoError(err) expiration := s.ctx.HeaderInfo().Time.Add(1 * time.Second) // must be in the future @@ -505,7 +503,7 @@ func (s *TestSuite) TestGetAuthorization() { genAuthMulti := authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgMultiSend{})) genAuthSend := authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgSend{})) - sendAuth := banktypes.NewSendAuthorization(coins10, nil, s.accountKeeper.AddressCodec()) + sendAuth := banktypes.NewSendAuthorization(coins10, nil, s.addrCdc) start := s.ctx.HeaderInfo().Time expired := start.Add(time.Duration(1) * time.Second) diff --git a/x/authz/keeper/msg_server.go b/x/authz/keeper/msg_server.go index 1722a4f0bb14..ecacf6e50521 100644 --- a/x/authz/keeper/msg_server.go +++ b/x/authz/keeper/msg_server.go @@ -20,12 +20,12 @@ func (k Keeper) Grant(ctx context.Context, msg *authz.MsgGrant) (*authz.MsgGrant return nil, authz.ErrGranteeIsGranter } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(msg.Grantee) + grantee, err := k.addrCdc.StringToBytes(msg.Grantee) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid grantee address: %s", err) } - granter, err := k.authKeeper.AddressCodec().StringToBytes(msg.Granter) + granter, err := k.addrCdc.StringToBytes(msg.Granter) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid granter address: %s", err) } @@ -64,12 +64,12 @@ func (k Keeper) Revoke(ctx context.Context, msg *authz.MsgRevoke) (*authz.MsgRev return nil, authz.ErrGranteeIsGranter } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(msg.Grantee) + grantee, err := k.addrCdc.StringToBytes(msg.Grantee) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid grantee address: %s", err) } - granter, err := k.authKeeper.AddressCodec().StringToBytes(msg.Granter) + granter, err := k.addrCdc.StringToBytes(msg.Granter) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid granter address: %s", err) } @@ -87,7 +87,7 @@ func (k Keeper) Revoke(ctx context.Context, msg *authz.MsgRevoke) (*authz.MsgRev // RevokeAll implements the MsgServer.RevokeAll method. func (k Keeper) RevokeAll(ctx context.Context, msg *authz.MsgRevokeAll) (*authz.MsgRevokeAllResponse, error) { - granter, err := k.authKeeper.AddressCodec().StringToBytes(msg.Granter) + granter, err := k.addrCdc.StringToBytes(msg.Granter) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid granter address: %s", err) } @@ -105,7 +105,7 @@ func (k Keeper) Exec(ctx context.Context, msg *authz.MsgExec) (*authz.MsgExecRes return nil, errors.New("empty address string is not allowed") } - grantee, err := k.authKeeper.AddressCodec().StringToBytes(msg.Grantee) + grantee, err := k.addrCdc.StringToBytes(msg.Grantee) if err != nil { return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid grantee address: %s", err) } diff --git a/x/authz/keeper/msg_server_test.go b/x/authz/keeper/msg_server_test.go index 2958e45a9915..fe19fb4247da 100644 --- a/x/authz/keeper/msg_server_test.go +++ b/x/authz/keeper/msg_server_test.go @@ -3,23 +3,17 @@ package keeper_test import ( "time" - "github.com/golang/mock/gomock" - "cosmossdk.io/core/header" sdkmath "cosmossdk.io/math" "cosmossdk.io/x/authz" banktypes "cosmossdk.io/x/bank/types" - "github.com/cosmos/cosmos-sdk/codec/address" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) func (suite *TestSuite) createAccounts() []sdk.AccAddress { addrs := simtestutil.CreateIncrementalAccounts(2) - suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), suite.addrs[0]).Return(authtypes.NewBaseAccountWithAddress(suite.addrs[0])).AnyTimes() - suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), suite.addrs[1]).Return(authtypes.NewBaseAccountWithAddress(suite.addrs[1])).AnyTimes() return addrs } @@ -28,17 +22,15 @@ func (suite *TestSuite) TestGrant() { addrs := suite.createAccounts() curBlockTime := ctx.HeaderInfo().Time - suite.accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() - oneHour := curBlockTime.Add(time.Hour) oneYear := curBlockTime.AddDate(1, 0, 0) coins := sdk.NewCoins(sdk.NewCoin("steak", sdkmath.NewInt(10))) grantee, granter := addrs[0], addrs[1] - granterStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(granter) + granterStrAddr, err := suite.addrCdc.BytesToString(granter) suite.Require().NoError(err) - granteeStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(grantee) + granteeStrAddr, err := suite.addrCdc.BytesToString(grantee) suite.Require().NoError(err) testCases := []struct { @@ -50,7 +42,7 @@ func (suite *TestSuite) TestGrant() { { name: "identical grantee and granter", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneYear) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granteeStrAddr, @@ -64,7 +56,7 @@ func (suite *TestSuite) TestGrant() { { name: "invalid granter", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneYear) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: "invalid", @@ -78,7 +70,7 @@ func (suite *TestSuite) TestGrant() { { name: "invalid grantee", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneYear) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granterStrAddr, @@ -107,7 +99,7 @@ func (suite *TestSuite) TestGrant() { name: "invalid grant, past time", malleate: func() *authz.MsgGrant { pTime := curBlockTime.Add(-time.Hour) - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneHour) // we only need the authorization + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneHour) // we only need the authorization suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granterStrAddr, @@ -125,14 +117,10 @@ func (suite *TestSuite) TestGrant() { name: "grantee account does not exist on chain: valid grant", malleate: func() *authz.MsgGrant { newAcc := sdk.AccAddress("valid") - suite.accountKeeper.EXPECT().GetAccount(gomock.Any(), newAcc).Return(nil).AnyTimes() - acc := authtypes.NewBaseAccountWithAddress(newAcc) - suite.accountKeeper.EXPECT().NewAccountWithAddress(gomock.Any(), newAcc).Return(acc).AnyTimes() - - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneYear) suite.Require().NoError(err) - addr, err := suite.accountKeeper.AddressCodec().BytesToString(newAcc) + addr, err := suite.addrCdc.BytesToString(newAcc) suite.Require().NoError(err) return &authz.MsgGrant{ @@ -145,7 +133,7 @@ func (suite *TestSuite) TestGrant() { { name: "valid grant", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneYear) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granterStrAddr, @@ -157,7 +145,7 @@ func (suite *TestSuite) TestGrant() { { name: "valid grant, same grantee, granter pair but different msgType", malleate: func() *authz.MsgGrant { - g, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &oneHour) + g, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &oneHour) suite.Require().NoError(err) _, err = suite.msgSrvr.Grant(suite.ctx, &authz.MsgGrant{ Granter: granterStrAddr, @@ -178,7 +166,7 @@ func (suite *TestSuite) TestGrant() { { name: "valid grant with allow list", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, []sdk.AccAddress{granter}, suite.accountKeeper.AddressCodec()), &oneYear) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, []sdk.AccAddress{granter}, suite.addrCdc), &oneYear) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granterStrAddr, @@ -190,7 +178,7 @@ func (suite *TestSuite) TestGrant() { { name: "valid grant with nil expiration time", malleate: func() *authz.MsgGrant { - grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), nil) + grant, err := authz.NewGrant(curBlockTime, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), nil) suite.Require().NoError(err) return &authz.MsgGrant{ Granter: granterStrAddr, @@ -232,9 +220,9 @@ func (suite *TestSuite) TestRevoke() { addrs := suite.createAccounts() grantee, granter := addrs[0], addrs[1] - granterStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(granter) + granterStrAddr, err := suite.addrCdc.BytesToString(granter) suite.Require().NoError(err) - granteeStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(grantee) + granteeStrAddr, err := suite.addrCdc.BytesToString(grantee) suite.Require().NoError(err) testCases := []struct { @@ -334,9 +322,9 @@ func (suite *TestSuite) TestExec() { addrs := suite.createAccounts() grantee, granter := addrs[0], addrs[1] - granterStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(granter) + granterStrAddr, err := suite.addrCdc.BytesToString(granter) suite.Require().NoError(err) - granteeStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(grantee) + granteeStrAddr, err := suite.addrCdc.BytesToString(grantee) suite.Require().NoError(err) coins := sdk.NewCoins(sdk.NewCoin("steak", sdkmath.NewInt(10))) @@ -402,15 +390,15 @@ func (suite *TestSuite) TestExec() { func (suite *TestSuite) TestPruneExpiredGrants() { addrs := suite.createAccounts() - addr0, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[0]) + addr0, err := suite.addrCdc.BytesToString(addrs[0]) suite.Require().NoError(err) - addr1, err := suite.accountKeeper.AddressCodec().BytesToString(addrs[1]) + addr1, err := suite.addrCdc.BytesToString(addrs[1]) suite.Require().NoError(err) timeNow := suite.ctx.BlockTime() expiration := timeNow.Add(time.Hour) coins := sdk.NewCoins(sdk.NewCoin("steak", sdkmath.NewInt(10))) - grant, err := authz.NewGrant(timeNow, banktypes.NewSendAuthorization(coins, nil, suite.accountKeeper.AddressCodec()), &expiration) + grant, err := authz.NewGrant(timeNow, banktypes.NewSendAuthorization(coins, nil, suite.addrCdc), &expiration) suite.Require().NoError(err) _, err = suite.msgSrvr.Grant(suite.ctx, &authz.MsgGrant{ @@ -454,7 +442,7 @@ func (suite *TestSuite) TestRevokeAllGrants() { addrs := simtestutil.CreateIncrementalAccounts(3) grantee, grantee2, granter := addrs[0], addrs[1], addrs[2] - granterStrAddr, err := suite.accountKeeper.AddressCodec().BytesToString(granter) + granterStrAddr, err := suite.addrCdc.BytesToString(granter) suite.Require().NoError(err) testCases := []struct { diff --git a/x/authz/module/abci_test.go b/x/authz/module/abci_test.go index 58811ba6294e..4696a1194ee9 100644 --- a/x/authz/module/abci_test.go +++ b/x/authz/module/abci_test.go @@ -4,7 +4,6 @@ import ( "testing" "time" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "cosmossdk.io/core/header" @@ -14,7 +13,6 @@ import ( "cosmossdk.io/x/authz" "cosmossdk.io/x/authz/keeper" authzmodule "cosmossdk.io/x/authz/module" - authztestutil "cosmossdk.io/x/authz/testutil" banktypes "cosmossdk.io/x/bank/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -25,7 +23,6 @@ import ( simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) func TestExpiredGrantsQueue(t *testing.T) { @@ -57,22 +54,13 @@ func TestExpiredGrantsQueue(t *testing.T) { smallCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 10)) sendAuthz := banktypes.NewSendAuthorization(smallCoins, nil, codectestutil.CodecOptions{}.GetAddressCodec()) - ctrl := gomock.NewController(t) - accountKeeper := authztestutil.NewMockAccountKeeper(ctrl) - accountKeeper.EXPECT().GetAccount(gomock.Any(), granter).Return(authtypes.NewBaseAccountWithAddress(granter)).AnyTimes() - accountKeeper.EXPECT().GetAccount(gomock.Any(), grantee1).Return(authtypes.NewBaseAccountWithAddress(grantee1)).AnyTimes() - accountKeeper.EXPECT().GetAccount(gomock.Any(), grantee2).Return(authtypes.NewBaseAccountWithAddress(grantee2)).AnyTimes() - accountKeeper.EXPECT().GetAccount(gomock.Any(), grantee3).Return(authtypes.NewBaseAccountWithAddress(grantee3)).AnyTimes() - accountKeeper.EXPECT().GetAccount(gomock.Any(), grantee4).Return(authtypes.NewBaseAccountWithAddress(grantee4)).AnyTimes() - - accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() - + addrCdc := address.NewBech32Codec("cosmos") env := runtime.NewEnvironment(storeService, coretesting.NewNopLogger(), runtime.EnvWithQueryRouterService(baseApp.GRPCQueryRouter()), runtime.EnvWithMsgRouterService(baseApp.MsgServiceRouter())) - authzKeeper := keeper.NewKeeper(env, encCfg.Codec, accountKeeper) + authzKeeper := keeper.NewKeeper(env, encCfg.Codec, addrCdc) save := func(grantee sdk.AccAddress, exp *time.Time) { err := authzKeeper.SaveGrant(ctx, grantee, granter, sendAuthz, exp) - addr, _ := accountKeeper.AddressCodec().BytesToString(grantee) + addr, _ := addrCdc.BytesToString(grantee) require.NoError(t, err, "Grant from %s", addr) } save(grantee1, &expiration) @@ -88,7 +76,7 @@ func TestExpiredGrantsQueue(t *testing.T) { err := authzmodule.BeginBlocker(ctx, authzKeeper) require.NoError(t, err) - addr, err := accountKeeper.AddressCodec().BytesToString(granter) + addr, err := addrCdc.BytesToString(granter) require.NoError(t, err) res, err := queryClient.GranterGrants(ctx.Context(), &authz.QueryGranterGrantsRequest{ Granter: addr, diff --git a/x/authz/module/depinject.go b/x/authz/module/depinject.go index 911bca8c1daa..4a9368053c93 100644 --- a/x/authz/module/depinject.go +++ b/x/authz/module/depinject.go @@ -2,10 +2,10 @@ package module import ( modulev1 "cosmossdk.io/api/cosmos/authz/module/v1" + "cosmossdk.io/core/address" "cosmossdk.io/core/appmodule" "cosmossdk.io/depinject" "cosmossdk.io/depinject/appconfig" - "cosmossdk.io/x/authz" "cosmossdk.io/x/authz/keeper" "github.com/cosmos/cosmos-sdk/codec" @@ -27,10 +27,10 @@ func init() { type ModuleInputs struct { depinject.In - Cdc codec.Codec - AccountKeeper authz.AccountKeeper - Registry cdctypes.InterfaceRegistry - Environment appmodule.Environment + Cdc codec.Codec + AddressCodec address.Codec + Registry cdctypes.InterfaceRegistry + Environment appmodule.Environment } type ModuleOutputs struct { @@ -41,7 +41,7 @@ type ModuleOutputs struct { } func ProvideModule(in ModuleInputs) ModuleOutputs { - k := keeper.NewKeeper(in.Environment, in.Cdc, in.AccountKeeper) + k := keeper.NewKeeper(in.Environment, in.Cdc, in.AddressCodec) m := NewAppModule(in.Cdc, k, in.Registry) return ModuleOutputs{AuthzKeeper: k, Module: m} } diff --git a/x/authz/testutil/expected_keepers_mocks.go b/x/authz/testutil/expected_keepers_mocks.go index df0bcb0e835f..0a2d645dd6d2 100644 --- a/x/authz/testutil/expected_keepers_mocks.go +++ b/x/authz/testutil/expected_keepers_mocks.go @@ -8,76 +8,10 @@ import ( context "context" reflect "reflect" - address "cosmossdk.io/core/address" types "github.com/cosmos/cosmos-sdk/types" gomock "github.com/golang/mock/gomock" ) -// MockAccountKeeper is a mock of AccountKeeper interface. -type MockAccountKeeper struct { - ctrl *gomock.Controller - recorder *MockAccountKeeperMockRecorder -} - -// MockAccountKeeperMockRecorder is the mock recorder for MockAccountKeeper. -type MockAccountKeeperMockRecorder struct { - mock *MockAccountKeeper -} - -// NewMockAccountKeeper creates a new mock instance. -func NewMockAccountKeeper(ctrl *gomock.Controller) *MockAccountKeeper { - mock := &MockAccountKeeper{ctrl: ctrl} - mock.recorder = &MockAccountKeeperMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockAccountKeeper) EXPECT() *MockAccountKeeperMockRecorder { - return m.recorder -} - -// AddressCodec mocks base method. -func (m *MockAccountKeeper) AddressCodec() address.Codec { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddressCodec") - ret0, _ := ret[0].(address.Codec) - return ret0 -} - -// AddressCodec indicates an expected call of AddressCodec. -func (mr *MockAccountKeeperMockRecorder) AddressCodec() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddressCodec", reflect.TypeOf((*MockAccountKeeper)(nil).AddressCodec)) -} - -// GetAccount mocks base method. -func (m *MockAccountKeeper) GetAccount(ctx context.Context, addr types.AccAddress) types.AccountI { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAccount", ctx, addr) - ret0, _ := ret[0].(types.AccountI) - return ret0 -} - -// GetAccount indicates an expected call of GetAccount. -func (mr *MockAccountKeeperMockRecorder) GetAccount(ctx, addr interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccount", reflect.TypeOf((*MockAccountKeeper)(nil).GetAccount), ctx, addr) -} - -// NewAccountWithAddress mocks base method. -func (m *MockAccountKeeper) NewAccountWithAddress(ctx context.Context, addr types.AccAddress) types.AccountI { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewAccountWithAddress", ctx, addr) - ret0, _ := ret[0].(types.AccountI) - return ret0 -} - -// NewAccountWithAddress indicates an expected call of NewAccountWithAddress. -func (mr *MockAccountKeeperMockRecorder) NewAccountWithAddress(ctx, addr interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAccountWithAddress", reflect.TypeOf((*MockAccountKeeper)(nil).NewAccountWithAddress), ctx, addr) -} - // MockBankKeeper is a mock of BankKeeper interface. type MockBankKeeper struct { ctrl *gomock.Controller From 814d4cf6b7a4441f0deff76baea0c0f78f356541 Mon Sep 17 00:00:00 2001 From: Eric Mokaya <4112301+ziscky@users.noreply.github.com> Date: Tue, 1 Oct 2024 10:35:58 +0300 Subject: [PATCH 05/10] feat(x/staking)!: Add metadata field to validator info (#21315) --- api/cosmos/staking/v1beta1/staking.pulsar.go | 1715 +++++++++---- .../grpc/gogoreflection/fix_registration.go | 12 +- simapp/simd/cmd/testnet.go | 2 +- simapp/v2/simdv2/cmd/testnet.go | 2 +- tests/integration/gov/common_test.go | 2 +- tests/integration/slashing/slashing_test.go | 2 +- .../staking/keeper/deterministic_test.go | 41 +- .../staking/keeper/genesis_test.go | 10 +- .../staking/keeper/msg_server_test.go | 2 +- .../tx/aminojson/aminojson_test.go | 10 +- testutil/network/network.go | 2 +- x/auth/vesting/types/vesting.pb.go | 2 +- x/genutil/gentx_test.go | 2 +- x/genutil/types/genesis_state_test.go | 4 +- x/staking/CHANGELOG.md | 11 +- x/staking/client/cli/flags.go | 16 +- x/staking/client/cli/tx.go | 25 +- x/staking/client/cli/utils.go | 40 +- x/staking/keeper/keeper_test.go | 4 +- x/staking/keeper/msg_server.go | 4 +- x/staking/proto/buf.lock | 19 +- .../cosmos/staking/v1beta1/staking.proto | 30 +- x/staking/simulation/msg_factory.go | 10 +- x/staking/simulation/rand_util.go | 36 + x/staking/simulation/rand_util_test.go | 60 + x/staking/types/msg.go | 2 +- x/staking/types/staking.pb.go | 2159 ++++++++++------- x/staking/types/validator.go | 45 +- 28 files changed, 2777 insertions(+), 1492 deletions(-) create mode 100644 x/staking/simulation/rand_util.go create mode 100644 x/staking/simulation/rand_util_test.go diff --git a/api/cosmos/staking/v1beta1/staking.pulsar.go b/api/cosmos/staking/v1beta1/staking.pulsar.go index 3b0e5cb37861..c2f9457ca822 100644 --- a/api/cosmos/staking/v1beta1/staking.pulsar.go +++ b/api/cosmos/staking/v1beta1/staking.pulsar.go @@ -1663,6 +1663,7 @@ var ( fd_Description_website protoreflect.FieldDescriptor fd_Description_security_contact protoreflect.FieldDescriptor fd_Description_details protoreflect.FieldDescriptor + fd_Description_metadata protoreflect.FieldDescriptor ) func init() { @@ -1673,6 +1674,7 @@ func init() { fd_Description_website = md_Description.Fields().ByName("website") fd_Description_security_contact = md_Description.Fields().ByName("security_contact") fd_Description_details = md_Description.Fields().ByName("details") + fd_Description_metadata = md_Description.Fields().ByName("metadata") } var _ protoreflect.Message = (*fastReflection_Description)(nil) @@ -1770,6 +1772,12 @@ func (x *fastReflection_Description) Range(f func(protoreflect.FieldDescriptor, return } } + if x.Metadata != nil { + value := protoreflect.ValueOfMessage(x.Metadata.ProtoReflect()) + if !f(fd_Description_metadata, value) { + return + } + } } // Has reports whether a field is populated. @@ -1795,6 +1803,8 @@ func (x *fastReflection_Description) Has(fd protoreflect.FieldDescriptor) bool { return x.SecurityContact != "" case "cosmos.staking.v1beta1.Description.details": return x.Details != "" + case "cosmos.staking.v1beta1.Description.metadata": + return x.Metadata != nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Description")) @@ -1821,6 +1831,8 @@ func (x *fastReflection_Description) Clear(fd protoreflect.FieldDescriptor) { x.SecurityContact = "" case "cosmos.staking.v1beta1.Description.details": x.Details = "" + case "cosmos.staking.v1beta1.Description.metadata": + x.Metadata = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Description")) @@ -1852,6 +1864,9 @@ func (x *fastReflection_Description) Get(descriptor protoreflect.FieldDescriptor case "cosmos.staking.v1beta1.Description.details": value := x.Details return protoreflect.ValueOfString(value) + case "cosmos.staking.v1beta1.Description.metadata": + value := x.Metadata + return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Description")) @@ -1882,6 +1897,8 @@ func (x *fastReflection_Description) Set(fd protoreflect.FieldDescriptor, value x.SecurityContact = value.Interface().(string) case "cosmos.staking.v1beta1.Description.details": x.Details = value.Interface().(string) + case "cosmos.staking.v1beta1.Description.metadata": + x.Metadata = value.Message().Interface().(*Metadata) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Description")) @@ -1902,6 +1919,11 @@ func (x *fastReflection_Description) Set(fd protoreflect.FieldDescriptor, value // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Description) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { + case "cosmos.staking.v1beta1.Description.metadata": + if x.Metadata == nil { + x.Metadata = new(Metadata) + } + return protoreflect.ValueOfMessage(x.Metadata.ProtoReflect()) case "cosmos.staking.v1beta1.Description.moniker": panic(fmt.Errorf("field moniker of message cosmos.staking.v1beta1.Description is not mutable")) case "cosmos.staking.v1beta1.Description.identity": @@ -1935,6 +1957,9 @@ func (x *fastReflection_Description) NewField(fd protoreflect.FieldDescriptor) p return protoreflect.ValueOfString("") case "cosmos.staking.v1beta1.Description.details": return protoreflect.ValueOfString("") + case "cosmos.staking.v1beta1.Description.metadata": + m := new(Metadata) + return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Description")) @@ -2024,6 +2049,10 @@ func (x *fastReflection_Description) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + if x.Metadata != nil { + l = options.Size(x.Metadata) + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -2053,6 +2082,20 @@ func (x *fastReflection_Description) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if x.Metadata != nil { + encoded, err := options.Marshal(x.Metadata) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x32 + } if len(x.Details) > 0 { i -= len(x.Details) copy(dAtA[i:], x.Details) @@ -2228,14 +2271,594 @@ func (x *fastReflection_Description) ProtoMethods() *protoiface.Methods { if postIndex < 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength } - if postIndex > l { + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Website = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field SecurityContact", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.SecurityContact = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Details = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Metadata == nil { + x.Metadata = &Metadata{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Metadata); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var _ protoreflect.List = (*_Metadata_2_list)(nil) + +type _Metadata_2_list struct { + list *[]string +} + +func (x *_Metadata_2_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Metadata_2_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Metadata_2_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Metadata_2_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Metadata_2_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Metadata at list field SocialHandleUris as it is not of Message kind")) +} + +func (x *_Metadata_2_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Metadata_2_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Metadata_2_list) IsValid() bool { + return x.list != nil +} + +var ( + md_Metadata protoreflect.MessageDescriptor + fd_Metadata_profile_pic_uri protoreflect.FieldDescriptor + fd_Metadata_social_handle_uris protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_staking_v1beta1_staking_proto_init() + md_Metadata = File_cosmos_staking_v1beta1_staking_proto.Messages().ByName("Metadata") + fd_Metadata_profile_pic_uri = md_Metadata.Fields().ByName("profile_pic_uri") + fd_Metadata_social_handle_uris = md_Metadata.Fields().ByName("social_handle_uris") +} + +var _ protoreflect.Message = (*fastReflection_Metadata)(nil) + +type fastReflection_Metadata Metadata + +func (x *Metadata) ProtoReflect() protoreflect.Message { + return (*fastReflection_Metadata)(x) +} + +func (x *Metadata) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Metadata_messageType fastReflection_Metadata_messageType +var _ protoreflect.MessageType = fastReflection_Metadata_messageType{} + +type fastReflection_Metadata_messageType struct{} + +func (x fastReflection_Metadata_messageType) Zero() protoreflect.Message { + return (*fastReflection_Metadata)(nil) +} +func (x fastReflection_Metadata_messageType) New() protoreflect.Message { + return new(fastReflection_Metadata) +} +func (x fastReflection_Metadata_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Metadata +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Metadata) Descriptor() protoreflect.MessageDescriptor { + return md_Metadata +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Metadata) Type() protoreflect.MessageType { + return _fastReflection_Metadata_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Metadata) New() protoreflect.Message { + return new(fastReflection_Metadata) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Metadata) Interface() protoreflect.ProtoMessage { + return (*Metadata)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Metadata) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.ProfilePicUri != "" { + value := protoreflect.ValueOfString(x.ProfilePicUri) + if !f(fd_Metadata_profile_pic_uri, value) { + return + } + } + if len(x.SocialHandleUris) != 0 { + value := protoreflect.ValueOfList(&_Metadata_2_list{list: &x.SocialHandleUris}) + if !f(fd_Metadata_social_handle_uris, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Metadata) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + return x.ProfilePicUri != "" + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + return len(x.SocialHandleUris) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + x.ProfilePicUri = "" + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + x.SocialHandleUris = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Metadata) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + value := x.ProfilePicUri + return protoreflect.ValueOfString(value) + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + if len(x.SocialHandleUris) == 0 { + return protoreflect.ValueOfList(&_Metadata_2_list{}) + } + listValue := &_Metadata_2_list{list: &x.SocialHandleUris} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + x.ProfilePicUri = value.Interface().(string) + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + lv := value.List() + clv := lv.(*_Metadata_2_list) + x.SocialHandleUris = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + if x.SocialHandleUris == nil { + x.SocialHandleUris = []string{} + } + value := &_Metadata_2_list{list: &x.SocialHandleUris} + return protoreflect.ValueOfList(value) + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + panic(fmt.Errorf("field profile_pic_uri of message cosmos.staking.v1beta1.Metadata is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Metadata) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.staking.v1beta1.Metadata.profile_pic_uri": + return protoreflect.ValueOfString("") + case "cosmos.staking.v1beta1.Metadata.social_handle_uris": + list := []string{} + return protoreflect.ValueOfList(&_Metadata_2_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.staking.v1beta1.Metadata")) + } + panic(fmt.Errorf("message cosmos.staking.v1beta1.Metadata does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Metadata) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.staking.v1beta1.Metadata", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Metadata) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Metadata) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Metadata) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Metadata) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.ProfilePicUri) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.SocialHandleUris) > 0 { + for _, s := range x.SocialHandleUris { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Metadata) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.SocialHandleUris) > 0 { + for iNdEx := len(x.SocialHandleUris) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.SocialHandleUris[iNdEx]) + copy(dAtA[i:], x.SocialHandleUris[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.SocialHandleUris[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(x.ProfilePicUri) > 0 { + i -= len(x.ProfilePicUri) + copy(dAtA[i:], x.ProfilePicUri) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ProfilePicUri))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Metadata) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Website = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field SecurityContact", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ProfilePicUri", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2263,11 +2886,11 @@ func (x *fastReflection_Description) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.SecurityContact = string(dAtA[iNdEx:postIndex]) + x.ProfilePicUri = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field SocialHandleUris", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2295,7 +2918,7 @@ func (x *fastReflection_Description) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.Details = string(dAtA[iNdEx:postIndex]) + x.SocialHandleUris = append(x.SocialHandleUris, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -2422,7 +3045,7 @@ func (x *Validator) ProtoReflect() protoreflect.Message { } func (x *Validator) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[4] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3704,7 +4327,7 @@ func (x *ValAddresses) ProtoReflect() protoreflect.Message { } func (x *ValAddresses) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[5] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4140,7 +4763,7 @@ func (x *DVPair) ProtoReflect() protoreflect.Message { } func (x *DVPair) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[6] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4673,7 +5296,7 @@ func (x *DVPairs) ProtoReflect() protoreflect.Message { } func (x *DVPairs) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[7] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5120,7 +5743,7 @@ func (x *DVVTriplet) ProtoReflect() protoreflect.Message { } func (x *DVVTriplet) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[8] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5715,7 +6338,7 @@ func (x *DVVTriplets) ProtoReflect() protoreflect.Message { } func (x *DVVTriplets) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[9] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6162,7 +6785,7 @@ func (x *Delegation) ProtoReflect() protoreflect.Message { } func (x *Delegation) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[10] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6761,7 +7384,7 @@ func (x *UnbondingDelegation) ProtoReflect() protoreflect.Message { } func (x *UnbondingDelegation) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[11] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7338,7 +7961,7 @@ func (x *UnbondingDelegationEntry) ProtoReflect() protoreflect.Message { } func (x *UnbondingDelegationEntry) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[12] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8045,7 +8668,7 @@ func (x *RedelegationEntry) ProtoReflect() protoreflect.Message { } func (x *RedelegationEntry) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[13] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8799,7 +9422,7 @@ func (x *Redelegation) ProtoReflect() protoreflect.Message { } func (x *Redelegation) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[14] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9440,7 +10063,7 @@ func (x *Params) ProtoReflect() protoreflect.Message { } func (x *Params) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[15] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10216,7 +10839,7 @@ func (x *DelegationResponse) ProtoReflect() protoreflect.Message { } func (x *DelegationResponse) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[16] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10730,7 +11353,7 @@ func (x *RedelegationEntryResponse) ProtoReflect() protoreflect.Message { } func (x *RedelegationEntryResponse) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[17] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11280,7 +11903,7 @@ func (x *RedelegationResponse) ProtoReflect() protoreflect.Message { } func (x *RedelegationResponse) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[18] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11802,7 +12425,7 @@ func (x *Pool) ProtoReflect() protoreflect.Message { } func (x *Pool) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[19] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12335,7 +12958,7 @@ func (x *ValidatorUpdates) ProtoReflect() protoreflect.Message { } func (x *ValidatorUpdates) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[20] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12786,7 +13409,7 @@ func (x *ConsPubKeyRotationHistory) ProtoReflect() protoreflect.Message { } func (x *ConsPubKeyRotationHistory) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[21] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13531,7 +14154,7 @@ func (x *ValAddrsOfRotatedConsKeys) ProtoReflect() protoreflect.Message { } func (x *ValAddrsOfRotatedConsKeys) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[22] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14235,6 +14858,8 @@ type Description struct { SecurityContact string `protobuf:"bytes,4,opt,name=security_contact,json=securityContact,proto3" json:"security_contact,omitempty"` // details define other optional details. Details string `protobuf:"bytes,5,opt,name=details,proto3" json:"details,omitempty"` + // metadata defines extra information about the validator. + Metadata *Metadata `protobuf:"bytes,6,opt,name=metadata,proto3" json:"metadata,omitempty"` } func (x *Description) Reset() { @@ -14292,6 +14917,59 @@ func (x *Description) GetDetails() string { return "" } +func (x *Description) GetMetadata() *Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +// Metadata defines extra information about the validator. +type Metadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // profile_pic_uri defines a link to the validator profile picture. + ProfilePicUri string `protobuf:"bytes,1,opt,name=profile_pic_uri,json=profilePicUri,proto3" json:"profile_pic_uri,omitempty"` + // social_handle_uris defines a string array of uris to the validator's social handles. + SocialHandleUris []string `protobuf:"bytes,2,rep,name=social_handle_uris,json=socialHandleUris,proto3" json:"social_handle_uris,omitempty"` +} + +func (x *Metadata) Reset() { + *x = Metadata{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Metadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Metadata) ProtoMessage() {} + +// Deprecated: Use Metadata.ProtoReflect.Descriptor instead. +func (*Metadata) Descriptor() ([]byte, []int) { + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{4} +} + +func (x *Metadata) GetProfilePicUri() string { + if x != nil { + return x.ProfilePicUri + } + return "" +} + +func (x *Metadata) GetSocialHandleUris() []string { + if x != nil { + return x.SocialHandleUris + } + return nil +} + // Validator defines a validator, together with the total amount of the // Validator's bond shares and their exchange rate to coins. Slashing results in // a decrease in the exchange rate, allowing correct calculation of future @@ -14336,7 +15014,7 @@ type Validator struct { func (x *Validator) Reset() { *x = Validator{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[4] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14350,7 +15028,7 @@ func (*Validator) ProtoMessage() {} // Deprecated: Use Validator.ProtoReflect.Descriptor instead. func (*Validator) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{4} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{5} } func (x *Validator) GetOperatorAddress() string { @@ -14456,7 +15134,7 @@ type ValAddresses struct { func (x *ValAddresses) Reset() { *x = ValAddresses{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[5] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14470,7 +15148,7 @@ func (*ValAddresses) ProtoMessage() {} // Deprecated: Use ValAddresses.ProtoReflect.Descriptor instead. func (*ValAddresses) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{5} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{6} } func (x *ValAddresses) GetAddresses() []string { @@ -14495,7 +15173,7 @@ type DVPair struct { func (x *DVPair) Reset() { *x = DVPair{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[6] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14509,7 +15187,7 @@ func (*DVPair) ProtoMessage() {} // Deprecated: Use DVPair.ProtoReflect.Descriptor instead. func (*DVPair) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{6} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{7} } func (x *DVPair) GetDelegatorAddress() string { @@ -14538,7 +15216,7 @@ type DVPairs struct { func (x *DVPairs) Reset() { *x = DVPairs{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[7] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14552,7 +15230,7 @@ func (*DVPairs) ProtoMessage() {} // Deprecated: Use DVPairs.ProtoReflect.Descriptor instead. func (*DVPairs) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{7} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{8} } func (x *DVPairs) GetPairs() []*DVPair { @@ -14579,7 +15257,7 @@ type DVVTriplet struct { func (x *DVVTriplet) Reset() { *x = DVVTriplet{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[8] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14593,7 +15271,7 @@ func (*DVVTriplet) ProtoMessage() {} // Deprecated: Use DVVTriplet.ProtoReflect.Descriptor instead. func (*DVVTriplet) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{8} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{9} } func (x *DVVTriplet) GetDelegatorAddress() string { @@ -14629,7 +15307,7 @@ type DVVTriplets struct { func (x *DVVTriplets) Reset() { *x = DVVTriplets{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[9] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14643,7 +15321,7 @@ func (*DVVTriplets) ProtoMessage() {} // Deprecated: Use DVVTriplets.ProtoReflect.Descriptor instead. func (*DVVTriplets) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{9} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{10} } func (x *DVVTriplets) GetTriplets() []*DVVTriplet { @@ -14672,7 +15350,7 @@ type Delegation struct { func (x *Delegation) Reset() { *x = Delegation{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[10] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14686,7 +15364,7 @@ func (*Delegation) ProtoMessage() {} // Deprecated: Use Delegation.ProtoReflect.Descriptor instead. func (*Delegation) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{10} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{11} } func (x *Delegation) GetDelegatorAddress() string { @@ -14728,7 +15406,7 @@ type UnbondingDelegation struct { func (x *UnbondingDelegation) Reset() { *x = UnbondingDelegation{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[11] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14742,7 +15420,7 @@ func (*UnbondingDelegation) ProtoMessage() {} // Deprecated: Use UnbondingDelegation.ProtoReflect.Descriptor instead. func (*UnbondingDelegation) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{11} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{12} } func (x *UnbondingDelegation) GetDelegatorAddress() string { @@ -14789,7 +15467,7 @@ type UnbondingDelegationEntry struct { func (x *UnbondingDelegationEntry) Reset() { *x = UnbondingDelegationEntry{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[12] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14803,7 +15481,7 @@ func (*UnbondingDelegationEntry) ProtoMessage() {} // Deprecated: Use UnbondingDelegationEntry.ProtoReflect.Descriptor instead. func (*UnbondingDelegationEntry) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{12} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{13} } func (x *UnbondingDelegationEntry) GetCreationHeight() int64 { @@ -14871,7 +15549,7 @@ type RedelegationEntry struct { func (x *RedelegationEntry) Reset() { *x = RedelegationEntry{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[13] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14885,7 +15563,7 @@ func (*RedelegationEntry) ProtoMessage() {} // Deprecated: Use RedelegationEntry.ProtoReflect.Descriptor instead. func (*RedelegationEntry) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{13} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{14} } func (x *RedelegationEntry) GetCreationHeight() int64 { @@ -14950,7 +15628,7 @@ type Redelegation struct { func (x *Redelegation) Reset() { *x = Redelegation{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[14] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14964,7 +15642,7 @@ func (*Redelegation) ProtoMessage() {} // Deprecated: Use Redelegation.ProtoReflect.Descriptor instead. func (*Redelegation) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{14} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{15} } func (x *Redelegation) GetDelegatorAddress() string { @@ -15023,7 +15701,7 @@ type Params struct { func (x *Params) Reset() { *x = Params{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[15] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15037,7 +15715,7 @@ func (*Params) ProtoMessage() {} // Deprecated: Use Params.ProtoReflect.Descriptor instead. func (*Params) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{15} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{16} } func (x *Params) GetUnbondingTime() *durationpb.Duration { @@ -15104,7 +15782,7 @@ type DelegationResponse struct { func (x *DelegationResponse) Reset() { *x = DelegationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[16] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15118,7 +15796,7 @@ func (*DelegationResponse) ProtoMessage() {} // Deprecated: Use DelegationResponse.ProtoReflect.Descriptor instead. func (*DelegationResponse) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{16} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{17} } func (x *DelegationResponse) GetDelegation() *Delegation { @@ -15150,7 +15828,7 @@ type RedelegationEntryResponse struct { func (x *RedelegationEntryResponse) Reset() { *x = RedelegationEntryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[17] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15164,7 +15842,7 @@ func (*RedelegationEntryResponse) ProtoMessage() {} // Deprecated: Use RedelegationEntryResponse.ProtoReflect.Descriptor instead. func (*RedelegationEntryResponse) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{17} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{18} } func (x *RedelegationEntryResponse) GetRedelegationEntry() *RedelegationEntry { @@ -15196,7 +15874,7 @@ type RedelegationResponse struct { func (x *RedelegationResponse) Reset() { *x = RedelegationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[18] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15210,7 +15888,7 @@ func (*RedelegationResponse) ProtoMessage() {} // Deprecated: Use RedelegationResponse.ProtoReflect.Descriptor instead. func (*RedelegationResponse) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{18} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{19} } func (x *RedelegationResponse) GetRedelegation() *Redelegation { @@ -15241,7 +15919,7 @@ type Pool struct { func (x *Pool) Reset() { *x = Pool{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[19] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15255,7 +15933,7 @@ func (*Pool) ProtoMessage() {} // Deprecated: Use Pool.ProtoReflect.Descriptor instead. func (*Pool) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{19} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{20} } func (x *Pool) GetNotBondedTokens() string { @@ -15287,7 +15965,7 @@ type ValidatorUpdates struct { func (x *ValidatorUpdates) Reset() { *x = ValidatorUpdates{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[20] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15301,7 +15979,7 @@ func (*ValidatorUpdates) ProtoMessage() {} // Deprecated: Use ValidatorUpdates.ProtoReflect.Descriptor instead. func (*ValidatorUpdates) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{20} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{21} } func (x *ValidatorUpdates) GetUpdates() []*v11.ValidatorUpdate { @@ -15332,7 +16010,7 @@ type ConsPubKeyRotationHistory struct { func (x *ConsPubKeyRotationHistory) Reset() { *x = ConsPubKeyRotationHistory{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[21] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15346,7 +16024,7 @@ func (*ConsPubKeyRotationHistory) ProtoMessage() {} // Deprecated: Use ConsPubKeyRotationHistory.ProtoReflect.Descriptor instead. func (*ConsPubKeyRotationHistory) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{21} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{22} } func (x *ConsPubKeyRotationHistory) GetOperatorAddress() []byte { @@ -15397,7 +16075,7 @@ type ValAddrsOfRotatedConsKeys struct { func (x *ValAddrsOfRotatedConsKeys) Reset() { *x = ValAddrsOfRotatedConsKeys{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[22] + mi := &file_cosmos_staking_v1beta1_staking_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15411,7 +16089,7 @@ func (*ValAddrsOfRotatedConsKeys) ProtoMessage() {} // Deprecated: Use ValAddrsOfRotatedConsKeys.ProtoReflect.Descriptor instead. func (*ValAddrsOfRotatedConsKeys) Descriptor() ([]byte, []int) { - return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{22} + return file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP(), []int{23} } func (x *ValAddrsOfRotatedConsKeys) GetAddresses() [][]byte { @@ -15427,23 +16105,23 @@ var file_cosmos_staking_v1beta1_staking_proto_rawDesc = []byte{ 0x0a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x16, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, - 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x14, - 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x61, 0x6d, 0x69, - 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, - 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x76, - 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x63, - 0x6f, 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2f, 0x61, 0x62, 0x63, 0x69, 0x2f, 0x76, 0x31, 0x2f, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x98, 0x01, 0x0a, 0x0e, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x11, + 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1c, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2f, 0x61, 0x62, 0x63, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x1d, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, + 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x98, 0x01, 0x0a, 0x0e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, @@ -15483,7 +16161,7 @@ var file_cosmos_staking_v1beta1_staking_proto_rawDesc = []byte{ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x3a, 0x04, 0xe8, - 0xa0, 0x1f, 0x01, 0x22, 0xa8, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0xa0, 0x1f, 0x01, 0x22, 0xf1, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x6f, 0x6e, 0x69, 0x6b, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, @@ -15493,361 +16171,372 @@ var file_cosmos_staking_v1beta1_staking_proto_rawDesc = []byte{ 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0x9d, - 0x07, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x43, 0x0a, 0x10, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x52, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x12, 0x59, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x5f, 0x70, - 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, - 0x79, 0x42, 0x18, 0xca, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, - 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, - 0x6a, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6a, 0x61, - 0x69, 0x6c, 0x65, 0x64, 0x12, 0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, - 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x6f, - 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x43, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, - 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x06, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x5c, 0x0a, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x6f, 0x72, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x31, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, - 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, - 0x79, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, - 0x65, 0x63, 0x52, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x68, 0x61, - 0x72, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0xc8, - 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0f, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x12, 0x50, 0x0a, 0x0e, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, - 0xb0, 0x2a, 0x01, 0x52, 0x0d, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, - 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x6e, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x5f, 0x64, 0x65, - 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3e, - 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, - 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, - 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xda, 0xb4, 0x2d, 0x0f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x30, 0x2e, 0x34, 0x37, 0x52, 0x11, - 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x3c, 0x0a, 0x1b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6f, - 0x6e, 0x5f, 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x4f, 0x6e, 0x48, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x23, 0x0a, 0x0d, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x73, - 0x18, 0x0d, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0c, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x49, 0x64, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0x46, - 0x0a, 0x0c, 0x56, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x36, - 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x06, 0x44, 0x56, 0x50, 0x61, 0x69, - 0x72, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, - 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, - 0x1f, 0x00, 0x22, 0x4a, 0x0a, 0x07, 0x44, 0x56, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x3f, 0x0a, - 0x05, 0x70, 0x61, 0x69, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x56, 0x50, 0x61, 0x69, 0x72, 0x42, 0x09, 0xc8, 0xde, - 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x05, 0x70, 0x61, 0x69, 0x72, 0x73, 0x22, 0x8b, - 0x02, 0x0a, 0x0a, 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x12, 0x45, 0x0a, - 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x5f, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x53, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0x58, 0x0a, 0x0b, - 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x08, 0x74, - 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, - 0x74, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x08, 0x74, 0x72, - 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xf8, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x67, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x11, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, 0x06, - 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x31, 0xc8, 0xde, - 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, - 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, - 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, - 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, - 0x00, 0x22, 0x8d, 0x02, 0x0a, 0x13, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, - 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, - 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x4e, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, - 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x55, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, - 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x62, 0x6f, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, - 0x00, 0x22, 0x9b, 0x03, 0x0a, 0x18, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x27, - 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, - 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, - 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, - 0x74, 0x52, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x12, 0x45, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, - 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, - 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x62, 0x6f, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, - 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1b, 0x75, - 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x6c, 0x64, - 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4f, 0x6e, 0x48, 0x6f, 0x6c, - 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, - 0x9f, 0x03, 0x0a, 0x11, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x52, - 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, - 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, - 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, - 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, - 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x50, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, - 0x65, 0x73, 0x5f, 0x64, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x31, 0xc8, 0xde, - 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, - 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, - 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x52, - 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x44, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, - 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x0b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x3c, 0x0a, - 0x1b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, - 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4f, 0x6e, 0x48, - 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, - 0x01, 0x22, 0xdd, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, + 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x09, 0xc8, 0xde, + 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0x66, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, + 0x69, 0x63, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x50, 0x69, 0x63, 0x55, 0x72, 0x69, 0x12, 0x2c, 0x0a, 0x12, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x75, 0x72, 0x69, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x6c, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x55, 0x72, 0x69, 0x73, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, + 0x9d, 0x07, 0x0a, 0x09, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x43, 0x0a, + 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x52, 0x0f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x59, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x5f, + 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, + 0x6e, 0x79, 0x42, 0x18, 0xca, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x0f, 0x63, 0x6f, + 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, + 0x06, 0x6a, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6a, + 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, + 0x6f, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x43, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, + 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x06, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x5c, 0x0a, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x31, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, + 0x63, 0x79, 0x44, 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x44, 0x65, 0x63, 0x52, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x68, + 0x61, 0x72, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, + 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0f, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x12, 0x50, 0x0a, 0x0e, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, + 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0d, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, + 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x6e, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x5f, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x3e, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, + 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, + 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xda, 0xb4, 0x2d, 0x0f, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x30, 0x2e, 0x34, 0x37, 0x52, + 0x11, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x6c, 0x66, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x1b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, + 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x4f, 0x6e, 0x48, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, + 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0c, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x49, 0x64, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, + 0x46, 0x0a, 0x0c, 0x56, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, + 0x36, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x06, 0x44, 0x56, 0x50, 0x61, + 0x69, 0x72, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x11, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, + 0xa0, 0x1f, 0x00, 0x22, 0x4a, 0x0a, 0x07, 0x44, 0x56, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x3f, + 0x0a, 0x05, 0x70, 0x61, 0x69, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x56, 0x50, 0x61, 0x69, 0x72, 0x42, 0x09, 0xc8, + 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x05, 0x70, 0x61, 0x69, 0x72, 0x73, 0x22, + 0x8b, 0x02, 0x0a, 0x0a, 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x12, 0x45, + 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x5f, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x53, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x73, 0x74, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, + 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x73, 0x74, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0x58, 0x0a, + 0x0b, 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x08, + 0x74, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x56, 0x56, 0x54, 0x72, 0x69, 0x70, 0x6c, + 0x65, 0x74, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x08, 0x74, + 0x72, 0x69, 0x70, 0x6c, 0x65, 0x74, 0x73, 0x22, 0xf8, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, + 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x73, - 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x73, 0x74, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, - 0x00, 0x22, 0xeb, 0x03, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x4f, 0x0a, 0x0e, - 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, - 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x98, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0d, - 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, 0x0a, - 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x6e, 0x74, 0x72, - 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x45, 0x6e, - 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x12, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, - 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0d, 0x42, 0x02, 0x18, 0x01, 0x52, 0x11, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, - 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x6e, 0x64, - 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x6f, - 0x6e, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x84, 0x01, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x5f, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x54, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, + 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x31, 0xc8, + 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, + 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, + 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, + 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, + 0x1f, 0x00, 0x22, 0x8d, 0x02, 0x0a, 0x13, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, + 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, + 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x4e, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, + 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, + 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x55, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, + 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x62, 0x6f, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, + 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, + 0x1f, 0x00, 0x22, 0x9b, 0x03, 0x0a, 0x18, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, + 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0f, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, - 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0xf2, 0xde, 0x1f, 0x1a, 0x79, 0x61, - 0x6d, 0x6c, 0x3a, 0x22, 0x6d, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x22, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x11, 0x6d, 0x69, 0x6e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, 0x12, 0x49, - 0x0a, 0x10, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, - 0x65, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x0e, 0x6b, 0x65, 0x79, 0x52, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x65, 0x65, 0x3a, 0x24, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, - 0xe7, 0xb0, 0x2a, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x78, - 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, - 0xa9, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, - 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x65, 0x67, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, - 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0xcd, 0x01, 0x0a, 0x19, + 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, + 0x6e, 0x74, 0x52, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x12, 0x45, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, + 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, + 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x62, + 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x1b, + 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, 0x6f, 0x6c, + 0x64, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4f, 0x6e, 0x48, 0x6f, + 0x6c, 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, + 0x22, 0x9f, 0x03, 0x0a, 0x11, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x52, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, + 0xb0, 0x2a, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2b, 0xc8, 0xde, + 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, + 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x50, 0x0a, 0x0a, 0x73, 0x68, 0x61, + 0x72, 0x65, 0x73, 0x5f, 0x64, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x31, 0xc8, + 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, + 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, + 0x65, 0x63, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, + 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x44, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x75, + 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x64, 0x12, 0x3c, + 0x0a, 0x1b, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x6e, 0x5f, 0x68, + 0x6f, 0x6c, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x17, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4f, 0x6e, + 0x48, 0x6f, 0x6c, 0x64, 0x52, 0x65, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x04, 0xe8, 0xa0, + 0x1f, 0x01, 0x22, 0xdd, 0x02, 0x0a, 0x0c, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, + 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x73, 0x72, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x72, 0x63, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x55, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, + 0x73, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x21, 0xd2, 0xb4, 0x2d, 0x1d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x73, + 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, + 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3a, 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, + 0x1f, 0x00, 0x22, 0xeb, 0x03, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x4f, 0x0a, + 0x0e, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x0d, 0xc8, 0xde, 0x1f, 0x00, 0x98, 0xdf, 0x1f, 0x01, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, + 0x0d, 0x75, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x25, + 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x45, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x12, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0d, 0x42, 0x02, 0x18, 0x01, 0x52, 0x11, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, + 0x61, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x6e, + 0x64, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, + 0x6f, 0x6e, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x84, 0x01, 0x0a, 0x13, 0x6d, 0x69, 0x6e, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x54, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x1b, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, + 0x68, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x44, 0x65, 0x63, 0xf2, 0xde, 0x1f, 0x1a, 0x79, + 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6d, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x22, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x44, 0x65, 0x63, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x11, 0x6d, 0x69, + 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x74, 0x65, 0x12, + 0x49, 0x0a, 0x10, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x66, 0x65, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x0e, 0x6b, 0x65, 0x79, 0x52, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x65, 0x65, 0x3a, 0x24, 0xe8, 0xa0, 0x1f, 0x01, + 0x8a, 0xe7, 0xb0, 0x2a, 0x1b, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, + 0x78, 0x2f, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x22, 0xa9, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, + 0x69, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0xcd, 0x01, 0x0a, + 0x19, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x12, 0x72, 0x65, + 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x12, 0x72, 0x65, 0x64, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, - 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, - 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x11, 0x72, 0x65, 0x64, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x45, - 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, - 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, 0xb4, - 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x07, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0xc9, 0x01, 0x0a, 0x14, - 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0c, 0x72, 0x65, 0x64, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x56, 0x0a, 0x07, 0x65, 0x6e, 0x74, - 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0xc8, - 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0xeb, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x6f, 0x6c, - 0x12, 0x71, 0x0a, 0x11, 0x6e, 0x6f, 0x74, 0x5f, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x45, 0xc8, 0xde, 0x1f, - 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, - 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xea, 0xde, 0x1f, 0x11, 0x6e, 0x6f, - 0x74, 0x5f, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0xd2, - 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xa8, 0xe7, 0xb0, - 0x2a, 0x01, 0x52, 0x0f, 0x6e, 0x6f, 0x74, 0x42, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x73, 0x12, 0x66, 0x0a, 0x0d, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x41, 0xc8, 0xde, 0x1f, 0x00, - 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, - 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xea, 0xde, 0x1f, 0x0d, 0x62, 0x6f, 0x6e, - 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0c, 0x62, - 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x08, 0xe8, 0xa0, 0x1f, - 0x01, 0xf0, 0xa0, 0x1f, 0x01, 0x22, 0x5e, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x6f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x46, 0x0a, 0x07, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x6d, - 0x65, 0x74, 0x62, 0x66, 0x74, 0x2e, 0x61, 0x62, 0x63, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x09, 0xc8, - 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x73, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xd0, 0x02, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x73, 0x50, 0x75, - 0x62, 0x4b, 0x65, 0x79, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x6f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x56, - 0x0a, 0x0f, 0x6f, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x42, 0x18, 0xca, - 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, - 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x0d, 0x6f, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x73, - 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x56, 0x0a, 0x0f, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, - 0x6e, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x42, 0x18, 0xca, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, - 0x0d, 0x6e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x73, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x16, - 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x36, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, - 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x09, - 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, 0x08, - 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0x53, 0x0a, 0x19, 0x56, 0x61, 0x6c, 0x41, - 0x64, 0x64, 0x72, 0x73, 0x4f, 0x66, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, - 0x73, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x2a, 0xb6, 0x01, - 0x0a, 0x0a, 0x42, 0x6f, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x17, - 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x1a, 0x0f, 0x8a, 0x9d, 0x20, 0x0b, 0x55, - 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x14, 0x42, 0x4f, - 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x42, 0x4f, 0x4e, 0x44, - 0x45, 0x44, 0x10, 0x01, 0x1a, 0x0c, 0x8a, 0x9d, 0x20, 0x08, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, - 0x65, 0x64, 0x12, 0x28, 0x0a, 0x15, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x55, 0x4e, 0x42, 0x4f, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x1a, 0x0d, 0x8a, - 0x9d, 0x20, 0x09, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x22, 0x0a, 0x12, - 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x42, 0x4f, 0x4e, 0x44, - 0x45, 0x44, 0x10, 0x03, 0x1a, 0x0a, 0x8a, 0x9d, 0x20, 0x06, 0x42, 0x6f, 0x6e, 0x64, 0x65, 0x64, - 0x1a, 0x04, 0x88, 0xa3, 0x1e, 0x00, 0x2a, 0x5d, 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x72, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, - 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, - 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x54, - 0x49, 0x4d, 0x45, 0x10, 0x02, 0x42, 0xdc, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, + 0x79, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x11, 0x72, 0x65, + 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x45, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x2b, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xd2, + 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x07, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0xc9, 0x01, 0x0a, + 0x14, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0c, 0x72, 0x65, + 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x56, 0x0a, 0x07, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x42, 0x0c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, - 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x73, 0x74, - 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x73, 0x74, - 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, - 0x53, 0x58, 0xaa, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x6b, - 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x43, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x22, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, - 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x43, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, + 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x65, 0x73, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0xeb, 0x01, 0x0a, 0x04, 0x50, 0x6f, 0x6f, + 0x6c, 0x12, 0x71, 0x0a, 0x11, 0x6e, 0x6f, 0x74, 0x5f, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x45, 0xc8, 0xde, + 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, + 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xea, 0xde, 0x1f, 0x11, 0x6e, + 0x6f, 0x74, 0x5f, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0xd2, 0xb4, 0x2d, 0x0a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xa8, 0xe7, + 0xb0, 0x2a, 0x01, 0x52, 0x0f, 0x6e, 0x6f, 0x74, 0x42, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x66, 0x0a, 0x0d, 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x41, 0xc8, 0xde, 0x1f, + 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, + 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xea, 0xde, 0x1f, 0x0d, 0x62, 0x6f, + 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0xd2, 0xb4, 0x2d, 0x0a, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0c, + 0x62, 0x6f, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x08, 0xe8, 0xa0, + 0x1f, 0x01, 0xf0, 0xa0, 0x1f, 0x01, 0x22, 0x5e, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x46, 0x0a, 0x07, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, + 0x6d, 0x65, 0x74, 0x62, 0x66, 0x74, 0x2e, 0x61, 0x62, 0x63, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x09, + 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x73, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xd0, 0x02, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x73, 0x50, + 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x56, 0x0a, 0x0f, 0x6f, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6b, + 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x42, 0x18, + 0xca, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x6f, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x52, 0x0d, 0x6f, 0x6c, 0x64, 0x43, 0x6f, 0x6e, + 0x73, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x56, 0x0a, 0x0f, 0x6e, 0x65, 0x77, 0x5f, 0x63, + 0x6f, 0x6e, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x42, 0x18, 0xca, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, + 0x52, 0x0d, 0x6e, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x73, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, + 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x36, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, + 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x03, 0x66, 0x65, 0x65, 0x3a, + 0x08, 0x88, 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x00, 0x22, 0x53, 0x0a, 0x19, 0x56, 0x61, 0x6c, + 0x41, 0x64, 0x64, 0x72, 0x73, 0x4f, 0x66, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, + 0x6e, 0x73, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x2a, 0xb6, + 0x01, 0x0a, 0x0a, 0x42, 0x6f, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, + 0x17, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x1a, 0x0f, 0x8a, 0x9d, 0x20, 0x0b, + 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x14, 0x42, + 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x42, 0x4f, 0x4e, + 0x44, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x0c, 0x8a, 0x9d, 0x20, 0x08, 0x55, 0x6e, 0x62, 0x6f, 0x6e, + 0x64, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x15, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x42, 0x4f, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x1a, 0x0d, + 0x8a, 0x9d, 0x20, 0x09, 0x55, 0x6e, 0x62, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x22, 0x0a, + 0x12, 0x42, 0x4f, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x42, 0x4f, 0x4e, + 0x44, 0x45, 0x44, 0x10, 0x03, 0x1a, 0x0a, 0x8a, 0x9d, 0x20, 0x06, 0x42, 0x6f, 0x6e, 0x64, 0x65, + 0x64, 0x1a, 0x04, 0x88, 0xa3, 0x1e, 0x00, 0x2a, 0x5d, 0x0a, 0x0a, 0x49, 0x6e, 0x66, 0x72, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x10, 0x01, 0x12, 0x17, 0x0a, + 0x13, 0x49, 0x4e, 0x46, 0x52, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x4f, 0x57, 0x4e, + 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, 0x42, 0xdc, 0x01, 0x0a, 0x1a, 0x63, 0x6f, 0x6d, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, + 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x73, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x73, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, + 0x43, 0x53, 0x58, 0xaa, 0x02, 0x16, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x61, + 0x6b, 0x69, 0x6e, 0x67, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x16, 0x43, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x22, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x53, + 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x18, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x3a, 0x3a, 0x56, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -15863,7 +16552,7 @@ func file_cosmos_staking_v1beta1_staking_proto_rawDescGZIP() []byte { } var file_cosmos_staking_v1beta1_staking_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_cosmos_staking_v1beta1_staking_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_cosmos_staking_v1beta1_staking_proto_msgTypes = make([]protoimpl.MessageInfo, 24) var file_cosmos_staking_v1beta1_staking_proto_goTypes = []interface{}{ (BondStatus)(0), // 0: cosmos.staking.v1beta1.BondStatus (Infraction)(0), // 1: cosmos.staking.v1beta1.Infraction @@ -15871,64 +16560,66 @@ var file_cosmos_staking_v1beta1_staking_proto_goTypes = []interface{}{ (*CommissionRates)(nil), // 3: cosmos.staking.v1beta1.CommissionRates (*Commission)(nil), // 4: cosmos.staking.v1beta1.Commission (*Description)(nil), // 5: cosmos.staking.v1beta1.Description - (*Validator)(nil), // 6: cosmos.staking.v1beta1.Validator - (*ValAddresses)(nil), // 7: cosmos.staking.v1beta1.ValAddresses - (*DVPair)(nil), // 8: cosmos.staking.v1beta1.DVPair - (*DVPairs)(nil), // 9: cosmos.staking.v1beta1.DVPairs - (*DVVTriplet)(nil), // 10: cosmos.staking.v1beta1.DVVTriplet - (*DVVTriplets)(nil), // 11: cosmos.staking.v1beta1.DVVTriplets - (*Delegation)(nil), // 12: cosmos.staking.v1beta1.Delegation - (*UnbondingDelegation)(nil), // 13: cosmos.staking.v1beta1.UnbondingDelegation - (*UnbondingDelegationEntry)(nil), // 14: cosmos.staking.v1beta1.UnbondingDelegationEntry - (*RedelegationEntry)(nil), // 15: cosmos.staking.v1beta1.RedelegationEntry - (*Redelegation)(nil), // 16: cosmos.staking.v1beta1.Redelegation - (*Params)(nil), // 17: cosmos.staking.v1beta1.Params - (*DelegationResponse)(nil), // 18: cosmos.staking.v1beta1.DelegationResponse - (*RedelegationEntryResponse)(nil), // 19: cosmos.staking.v1beta1.RedelegationEntryResponse - (*RedelegationResponse)(nil), // 20: cosmos.staking.v1beta1.RedelegationResponse - (*Pool)(nil), // 21: cosmos.staking.v1beta1.Pool - (*ValidatorUpdates)(nil), // 22: cosmos.staking.v1beta1.ValidatorUpdates - (*ConsPubKeyRotationHistory)(nil), // 23: cosmos.staking.v1beta1.ConsPubKeyRotationHistory - (*ValAddrsOfRotatedConsKeys)(nil), // 24: cosmos.staking.v1beta1.ValAddrsOfRotatedConsKeys - (*v1.Header)(nil), // 25: cometbft.types.v1.Header - (*timestamppb.Timestamp)(nil), // 26: google.protobuf.Timestamp - (*anypb.Any)(nil), // 27: google.protobuf.Any - (*durationpb.Duration)(nil), // 28: google.protobuf.Duration - (*v1beta1.Coin)(nil), // 29: cosmos.base.v1beta1.Coin - (*v11.ValidatorUpdate)(nil), // 30: cometbft.abci.v1.ValidatorUpdate + (*Metadata)(nil), // 6: cosmos.staking.v1beta1.Metadata + (*Validator)(nil), // 7: cosmos.staking.v1beta1.Validator + (*ValAddresses)(nil), // 8: cosmos.staking.v1beta1.ValAddresses + (*DVPair)(nil), // 9: cosmos.staking.v1beta1.DVPair + (*DVPairs)(nil), // 10: cosmos.staking.v1beta1.DVPairs + (*DVVTriplet)(nil), // 11: cosmos.staking.v1beta1.DVVTriplet + (*DVVTriplets)(nil), // 12: cosmos.staking.v1beta1.DVVTriplets + (*Delegation)(nil), // 13: cosmos.staking.v1beta1.Delegation + (*UnbondingDelegation)(nil), // 14: cosmos.staking.v1beta1.UnbondingDelegation + (*UnbondingDelegationEntry)(nil), // 15: cosmos.staking.v1beta1.UnbondingDelegationEntry + (*RedelegationEntry)(nil), // 16: cosmos.staking.v1beta1.RedelegationEntry + (*Redelegation)(nil), // 17: cosmos.staking.v1beta1.Redelegation + (*Params)(nil), // 18: cosmos.staking.v1beta1.Params + (*DelegationResponse)(nil), // 19: cosmos.staking.v1beta1.DelegationResponse + (*RedelegationEntryResponse)(nil), // 20: cosmos.staking.v1beta1.RedelegationEntryResponse + (*RedelegationResponse)(nil), // 21: cosmos.staking.v1beta1.RedelegationResponse + (*Pool)(nil), // 22: cosmos.staking.v1beta1.Pool + (*ValidatorUpdates)(nil), // 23: cosmos.staking.v1beta1.ValidatorUpdates + (*ConsPubKeyRotationHistory)(nil), // 24: cosmos.staking.v1beta1.ConsPubKeyRotationHistory + (*ValAddrsOfRotatedConsKeys)(nil), // 25: cosmos.staking.v1beta1.ValAddrsOfRotatedConsKeys + (*v1.Header)(nil), // 26: cometbft.types.v1.Header + (*timestamppb.Timestamp)(nil), // 27: google.protobuf.Timestamp + (*anypb.Any)(nil), // 28: google.protobuf.Any + (*durationpb.Duration)(nil), // 29: google.protobuf.Duration + (*v1beta1.Coin)(nil), // 30: cosmos.base.v1beta1.Coin + (*v11.ValidatorUpdate)(nil), // 31: cometbft.abci.v1.ValidatorUpdate } var file_cosmos_staking_v1beta1_staking_proto_depIdxs = []int32{ - 25, // 0: cosmos.staking.v1beta1.HistoricalInfo.header:type_name -> cometbft.types.v1.Header - 6, // 1: cosmos.staking.v1beta1.HistoricalInfo.valset:type_name -> cosmos.staking.v1beta1.Validator + 26, // 0: cosmos.staking.v1beta1.HistoricalInfo.header:type_name -> cometbft.types.v1.Header + 7, // 1: cosmos.staking.v1beta1.HistoricalInfo.valset:type_name -> cosmos.staking.v1beta1.Validator 3, // 2: cosmos.staking.v1beta1.Commission.commission_rates:type_name -> cosmos.staking.v1beta1.CommissionRates - 26, // 3: cosmos.staking.v1beta1.Commission.update_time:type_name -> google.protobuf.Timestamp - 27, // 4: cosmos.staking.v1beta1.Validator.consensus_pubkey:type_name -> google.protobuf.Any - 0, // 5: cosmos.staking.v1beta1.Validator.status:type_name -> cosmos.staking.v1beta1.BondStatus - 5, // 6: cosmos.staking.v1beta1.Validator.description:type_name -> cosmos.staking.v1beta1.Description - 26, // 7: cosmos.staking.v1beta1.Validator.unbonding_time:type_name -> google.protobuf.Timestamp - 4, // 8: cosmos.staking.v1beta1.Validator.commission:type_name -> cosmos.staking.v1beta1.Commission - 8, // 9: cosmos.staking.v1beta1.DVPairs.pairs:type_name -> cosmos.staking.v1beta1.DVPair - 10, // 10: cosmos.staking.v1beta1.DVVTriplets.triplets:type_name -> cosmos.staking.v1beta1.DVVTriplet - 14, // 11: cosmos.staking.v1beta1.UnbondingDelegation.entries:type_name -> cosmos.staking.v1beta1.UnbondingDelegationEntry - 26, // 12: cosmos.staking.v1beta1.UnbondingDelegationEntry.completion_time:type_name -> google.protobuf.Timestamp - 26, // 13: cosmos.staking.v1beta1.RedelegationEntry.completion_time:type_name -> google.protobuf.Timestamp - 15, // 14: cosmos.staking.v1beta1.Redelegation.entries:type_name -> cosmos.staking.v1beta1.RedelegationEntry - 28, // 15: cosmos.staking.v1beta1.Params.unbonding_time:type_name -> google.protobuf.Duration - 29, // 16: cosmos.staking.v1beta1.Params.key_rotation_fee:type_name -> cosmos.base.v1beta1.Coin - 12, // 17: cosmos.staking.v1beta1.DelegationResponse.delegation:type_name -> cosmos.staking.v1beta1.Delegation - 29, // 18: cosmos.staking.v1beta1.DelegationResponse.balance:type_name -> cosmos.base.v1beta1.Coin - 15, // 19: cosmos.staking.v1beta1.RedelegationEntryResponse.redelegation_entry:type_name -> cosmos.staking.v1beta1.RedelegationEntry - 16, // 20: cosmos.staking.v1beta1.RedelegationResponse.redelegation:type_name -> cosmos.staking.v1beta1.Redelegation - 19, // 21: cosmos.staking.v1beta1.RedelegationResponse.entries:type_name -> cosmos.staking.v1beta1.RedelegationEntryResponse - 30, // 22: cosmos.staking.v1beta1.ValidatorUpdates.updates:type_name -> cometbft.abci.v1.ValidatorUpdate - 27, // 23: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.old_cons_pubkey:type_name -> google.protobuf.Any - 27, // 24: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.new_cons_pubkey:type_name -> google.protobuf.Any - 29, // 25: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.fee:type_name -> cosmos.base.v1beta1.Coin - 26, // [26:26] is the sub-list for method output_type - 26, // [26:26] is the sub-list for method input_type - 26, // [26:26] is the sub-list for extension type_name - 26, // [26:26] is the sub-list for extension extendee - 0, // [0:26] is the sub-list for field type_name + 27, // 3: cosmos.staking.v1beta1.Commission.update_time:type_name -> google.protobuf.Timestamp + 6, // 4: cosmos.staking.v1beta1.Description.metadata:type_name -> cosmos.staking.v1beta1.Metadata + 28, // 5: cosmos.staking.v1beta1.Validator.consensus_pubkey:type_name -> google.protobuf.Any + 0, // 6: cosmos.staking.v1beta1.Validator.status:type_name -> cosmos.staking.v1beta1.BondStatus + 5, // 7: cosmos.staking.v1beta1.Validator.description:type_name -> cosmos.staking.v1beta1.Description + 27, // 8: cosmos.staking.v1beta1.Validator.unbonding_time:type_name -> google.protobuf.Timestamp + 4, // 9: cosmos.staking.v1beta1.Validator.commission:type_name -> cosmos.staking.v1beta1.Commission + 9, // 10: cosmos.staking.v1beta1.DVPairs.pairs:type_name -> cosmos.staking.v1beta1.DVPair + 11, // 11: cosmos.staking.v1beta1.DVVTriplets.triplets:type_name -> cosmos.staking.v1beta1.DVVTriplet + 15, // 12: cosmos.staking.v1beta1.UnbondingDelegation.entries:type_name -> cosmos.staking.v1beta1.UnbondingDelegationEntry + 27, // 13: cosmos.staking.v1beta1.UnbondingDelegationEntry.completion_time:type_name -> google.protobuf.Timestamp + 27, // 14: cosmos.staking.v1beta1.RedelegationEntry.completion_time:type_name -> google.protobuf.Timestamp + 16, // 15: cosmos.staking.v1beta1.Redelegation.entries:type_name -> cosmos.staking.v1beta1.RedelegationEntry + 29, // 16: cosmos.staking.v1beta1.Params.unbonding_time:type_name -> google.protobuf.Duration + 30, // 17: cosmos.staking.v1beta1.Params.key_rotation_fee:type_name -> cosmos.base.v1beta1.Coin + 13, // 18: cosmos.staking.v1beta1.DelegationResponse.delegation:type_name -> cosmos.staking.v1beta1.Delegation + 30, // 19: cosmos.staking.v1beta1.DelegationResponse.balance:type_name -> cosmos.base.v1beta1.Coin + 16, // 20: cosmos.staking.v1beta1.RedelegationEntryResponse.redelegation_entry:type_name -> cosmos.staking.v1beta1.RedelegationEntry + 17, // 21: cosmos.staking.v1beta1.RedelegationResponse.redelegation:type_name -> cosmos.staking.v1beta1.Redelegation + 20, // 22: cosmos.staking.v1beta1.RedelegationResponse.entries:type_name -> cosmos.staking.v1beta1.RedelegationEntryResponse + 31, // 23: cosmos.staking.v1beta1.ValidatorUpdates.updates:type_name -> cometbft.abci.v1.ValidatorUpdate + 28, // 24: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.old_cons_pubkey:type_name -> google.protobuf.Any + 28, // 25: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.new_cons_pubkey:type_name -> google.protobuf.Any + 30, // 26: cosmos.staking.v1beta1.ConsPubKeyRotationHistory.fee:type_name -> cosmos.base.v1beta1.Coin + 27, // [27:27] is the sub-list for method output_type + 27, // [27:27] is the sub-list for method input_type + 27, // [27:27] is the sub-list for extension type_name + 27, // [27:27] is the sub-list for extension extendee + 0, // [0:27] is the sub-list for field type_name } func init() { file_cosmos_staking_v1beta1_staking_proto_init() } @@ -15986,7 +16677,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Validator); i { + switch v := v.(*Metadata); i { case 0: return &v.state case 1: @@ -15998,7 +16689,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValAddresses); i { + switch v := v.(*Validator); i { case 0: return &v.state case 1: @@ -16010,7 +16701,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DVPair); i { + switch v := v.(*ValAddresses); i { case 0: return &v.state case 1: @@ -16022,7 +16713,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DVPairs); i { + switch v := v.(*DVPair); i { case 0: return &v.state case 1: @@ -16034,7 +16725,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DVVTriplet); i { + switch v := v.(*DVPairs); i { case 0: return &v.state case 1: @@ -16046,7 +16737,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DVVTriplets); i { + switch v := v.(*DVVTriplet); i { case 0: return &v.state case 1: @@ -16058,7 +16749,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Delegation); i { + switch v := v.(*DVVTriplets); i { case 0: return &v.state case 1: @@ -16070,7 +16761,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnbondingDelegation); i { + switch v := v.(*Delegation); i { case 0: return &v.state case 1: @@ -16082,7 +16773,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnbondingDelegationEntry); i { + switch v := v.(*UnbondingDelegation); i { case 0: return &v.state case 1: @@ -16094,7 +16785,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RedelegationEntry); i { + switch v := v.(*UnbondingDelegationEntry); i { case 0: return &v.state case 1: @@ -16106,7 +16797,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Redelegation); i { + switch v := v.(*RedelegationEntry); i { case 0: return &v.state case 1: @@ -16118,7 +16809,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Params); i { + switch v := v.(*Redelegation); i { case 0: return &v.state case 1: @@ -16130,7 +16821,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DelegationResponse); i { + switch v := v.(*Params); i { case 0: return &v.state case 1: @@ -16142,7 +16833,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RedelegationEntryResponse); i { + switch v := v.(*DelegationResponse); i { case 0: return &v.state case 1: @@ -16154,7 +16845,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RedelegationResponse); i { + switch v := v.(*RedelegationEntryResponse); i { case 0: return &v.state case 1: @@ -16166,7 +16857,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Pool); i { + switch v := v.(*RedelegationResponse); i { case 0: return &v.state case 1: @@ -16178,7 +16869,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ValidatorUpdates); i { + switch v := v.(*Pool); i { case 0: return &v.state case 1: @@ -16190,7 +16881,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ConsPubKeyRotationHistory); i { + switch v := v.(*ValidatorUpdates); i { case 0: return &v.state case 1: @@ -16202,6 +16893,18 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { } } file_cosmos_staking_v1beta1_staking_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConsPubKeyRotationHistory); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_staking_v1beta1_staking_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ValAddrsOfRotatedConsKeys); i { case 0: return &v.state @@ -16220,7 +16923,7 @@ func file_cosmos_staking_v1beta1_staking_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cosmos_staking_v1beta1_staking_proto_rawDesc, NumEnums: 2, - NumMessages: 23, + NumMessages: 24, NumExtensions: 0, NumServices: 0, }, diff --git a/server/v2/api/grpc/gogoreflection/fix_registration.go b/server/v2/api/grpc/gogoreflection/fix_registration.go index d4edfc62b5e7..5704f054ff61 100644 --- a/server/v2/api/grpc/gogoreflection/fix_registration.go +++ b/server/v2/api/grpc/gogoreflection/fix_registration.go @@ -41,12 +41,12 @@ func getExtension(extID int32, m proto.Message) *gogoproto.ExtensionDesc { for id, desc := range proto.RegisteredExtensions(m) { //nolint:staticcheck // keep for backward compatibility if id == extID { return &gogoproto.ExtensionDesc{ - ExtendedType: desc.ExtendedType, - ExtensionType: desc.ExtensionType, - Field: desc.Field, - Name: desc.Name, - Tag: desc.Tag, - Filename: desc.Filename, + ExtendedType: desc.ExtendedType, + ExtensionType: desc.ExtensionType, + Field: desc.Field, + Name: desc.Name, + Tag: desc.Tag, + Filename: desc.Filename, } } } diff --git a/simapp/simd/cmd/testnet.go b/simapp/simd/cmd/testnet.go index 116307f63bf2..b7199b4cbafa 100644 --- a/simapp/simd/cmd/testnet.go +++ b/simapp/simd/cmd/testnet.go @@ -353,7 +353,7 @@ func initTestnetFiles( valStr, valPubKeys[i], sdk.NewCoin(args.bondTokenDenom, valTokens), - stakingtypes.NewDescription(nodeDirName, "", "", "", ""), + stakingtypes.NewDescription(nodeDirName, "", "", "", "", stakingtypes.Metadata{}), stakingtypes.NewCommissionRates(math.LegacyOneDec(), math.LegacyOneDec(), math.LegacyOneDec()), math.OneInt(), ) diff --git a/simapp/v2/simdv2/cmd/testnet.go b/simapp/v2/simdv2/cmd/testnet.go index 8b15f9ccd7ad..ae01310f9151 100644 --- a/simapp/v2/simdv2/cmd/testnet.go +++ b/simapp/v2/simdv2/cmd/testnet.go @@ -296,7 +296,7 @@ func initTestnetFiles[T transaction.Tx]( valStr, valPubKeys[i], sdk.NewCoin(args.bondTokenDenom, valTokens), - stakingtypes.NewDescription(nodeDirName, "", "", "", ""), + stakingtypes.NewDescription(nodeDirName, "", "", "", "", stakingtypes.Metadata{}), stakingtypes.NewCommissionRates(math.LegacyOneDec(), math.LegacyOneDec(), math.LegacyOneDec()), math.OneInt(), ) diff --git a/tests/integration/gov/common_test.go b/tests/integration/gov/common_test.go index ced80fc6ad84..f84bbc81a857 100644 --- a/tests/integration/gov/common_test.go +++ b/tests/integration/gov/common_test.go @@ -34,7 +34,7 @@ import ( var ( valTokens = sdk.TokensFromConsensusPower(42, sdk.DefaultPowerReduction) TestProposal = v1beta1.NewTextProposal("Test", "description") - TestDescription = stakingtypes.NewDescription("T", "E", "S", "T", "Z") + TestDescription = stakingtypes.NewDescription("T", "E", "S", "T", "Z", stakingtypes.Metadata{}) TestCommissionRates = stakingtypes.NewCommissionRates(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()) ) diff --git a/tests/integration/slashing/slashing_test.go b/tests/integration/slashing/slashing_test.go index 60fc4f1e5ac6..6c60ce295b5d 100644 --- a/tests/integration/slashing/slashing_test.go +++ b/tests/integration/slashing/slashing_test.go @@ -83,7 +83,7 @@ func TestSlashingMsgs(t *testing.T) { require.NoError(t, err) - description := stakingtypes.NewDescription("foo_moniker", "", "", "", "") + description := stakingtypes.NewDescription("foo_moniker", "", "", "", "", stakingtypes.Metadata{}) commission := stakingtypes.NewCommissionRates(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()) addrStrVal, err := valaddrCodec.BytesToString(addr1) diff --git a/tests/integration/staking/keeper/deterministic_test.go b/tests/integration/staking/keeper/deterministic_test.go index 4a15c7775a35..4b9afd591281 100644 --- a/tests/integration/staking/keeper/deterministic_test.go +++ b/tests/integration/staking/keeper/deterministic_test.go @@ -2,6 +2,8 @@ package keeper_test import ( "context" + "fmt" + "net/url" "testing" "time" @@ -214,6 +216,26 @@ func bondTypeGenerator() *rapid.Generator[stakingtypes.BondStatus] { }) } +func metadataGenerator() *rapid.Generator[stakingtypes.Metadata] { + return rapid.Custom(func(t *rapid.T) stakingtypes.Metadata { + return stakingtypes.Metadata{ + ProfilePicUri: generateUri(t), + SocialHandleUris: []string{generateUri(t), generateUri(t)}, + } + }) +} + +func generateUri(t *rapid.T) string { + host := fmt.Sprintf("%s.com", rapid.StringN(5, 250, 255).Draw(t, "host")) + path := rapid.StringN(5, 250, 255).Draw(t, "path") + uri := url.URL{ + Scheme: "https", + Host: host, + Path: path, + } + return uri.String() +} + // createValidator creates a validator with random values. func createValidator(t *testing.T, rt *rapid.T, _ *deterministicFixture) stakingtypes.Validator { t.Helper() @@ -233,6 +255,7 @@ func createValidator(t *testing.T, rt *rapid.T, _ *deterministicFixture) staking rapid.StringN(5, 250, 255).Draw(rt, "website"), rapid.StringN(5, 250, 255).Draw(rt, "securityContact"), rapid.StringN(5, 250, 255).Draw(rt, "details"), + metadataGenerator().Draw(rt, "metadata"), ), UnbondingHeight: rapid.Int64Min(1).Draw(rt, "unbonding-height"), UnbondingTime: time.Now().Add(durationGenerator().Draw(rt, "duration")), @@ -308,6 +331,7 @@ func getStaticValidator(t *testing.T, f *deterministicFixture) stakingtypes.Vali "website", "securityContact", "details", + stakingtypes.Metadata{}, ), UnbondingHeight: 10, UnbondingTime: time.Date(2022, 10, 1, 0, 0, 0, 0, time.UTC), @@ -343,6 +367,7 @@ func getStaticValidator2(t *testing.T, f *deterministicFixture) stakingtypes.Val "website", "securityContact", "details", + stakingtypes.Metadata{}, ), UnbondingHeight: 100132, UnbondingTime: time.Date(2025, 10, 1, 0, 0, 0, 0, time.UTC), @@ -408,7 +433,7 @@ func TestGRPCValidator(t *testing.T) { ValidatorAddr: val.OperatorAddress, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Validator, 1915, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Validator, 1921, false) } func TestGRPCValidators(t *testing.T) { @@ -434,7 +459,7 @@ func TestGRPCValidators(t *testing.T) { getStaticValidator(t, f) getStaticValidator2(t, f) - testdata.DeterministicIterations(t, f.ctx, &stakingtypes.QueryValidatorsRequest{}, f.queryClient.Validators, 2862, false) + testdata.DeterministicIterations(t, f.ctx, &stakingtypes.QueryValidatorsRequest{}, f.queryClient.Validators, 2880, false) } func TestGRPCValidatorDelegations(t *testing.T) { @@ -479,7 +504,7 @@ func TestGRPCValidatorDelegations(t *testing.T) { ValidatorAddr: validator.OperatorAddress, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.ValidatorDelegations, 14610, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.ValidatorDelegations, 14628, false) } func TestGRPCValidatorUnbondingDelegations(t *testing.T) { @@ -569,7 +594,7 @@ func TestGRPCDelegation(t *testing.T) { DelegatorAddr: delegator1, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Delegation, 4680, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Delegation, 4686, false) } func TestGRPCUnbondingDelegation(t *testing.T) { @@ -652,7 +677,7 @@ func TestGRPCDelegatorDelegations(t *testing.T) { DelegatorAddr: delegator1, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorDelegations, 4283, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorDelegations, 4289, false) } func TestGRPCDelegatorValidator(t *testing.T) { @@ -690,7 +715,7 @@ func TestGRPCDelegatorValidator(t *testing.T) { ValidatorAddr: validator.OperatorAddress, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorValidator, 3563, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorValidator, 3569, false) } func TestGRPCDelegatorUnbondingDelegations(t *testing.T) { @@ -772,7 +797,7 @@ func TestGRPCDelegatorValidators(t *testing.T) { assert.NilError(t, err) req := &stakingtypes.QueryDelegatorValidatorsRequest{DelegatorAddr: delegator1} - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorValidators, 3166, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.DelegatorValidators, 3172, false) } func TestGRPCPool(t *testing.T) { @@ -856,7 +881,7 @@ func TestGRPCRedelegations(t *testing.T) { DstValidatorAddr: validator2, } - testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Redelegations, 3920, false) + testdata.DeterministicIterations(t, f.ctx, req, f.queryClient.Redelegations, 3926, false) } func TestGRPCParams(t *testing.T) { diff --git a/tests/integration/staking/keeper/genesis_test.go b/tests/integration/staking/keeper/genesis_test.go index 95e34da18485..da9fd6c5d660 100644 --- a/tests/integration/staking/keeper/genesis_test.go +++ b/tests/integration/staking/keeper/genesis_test.go @@ -41,7 +41,7 @@ func TestInitGenesis(t *testing.T) { Status: types.Bonded, Tokens: valTokens, DelegatorShares: math.LegacyNewDecFromInt(valTokens), - Description: types.NewDescription("hoop", "", "", "", ""), + Description: types.NewDescription("hoop", "", "", "", "", types.Metadata{}), } assert.NilError(t, f.stakingKeeper.SetValidator(f.sdkCtx, bondedVal)) @@ -67,7 +67,7 @@ func TestInitGenesis(t *testing.T) { Status: types.Bonded, Tokens: valTokens, DelegatorShares: math.LegacyNewDecFromInt(valTokens), - Description: types.NewDescription("hoop", "", "", "", ""), + Description: types.NewDescription("hoop", "", "", "", "", types.Metadata{}), } bondedVal2 := types.Validator{ OperatorAddress: sdk.ValAddress(addrs[2]).String(), @@ -75,7 +75,7 @@ func TestInitGenesis(t *testing.T) { Status: types.Bonded, Tokens: valTokens, DelegatorShares: math.LegacyNewDecFromInt(valTokens), - Description: types.NewDescription("bloop", "", "", "", ""), + Description: types.NewDescription("bloop", "", "", "", "", types.Metadata{}), } // append new bonded validators to the list @@ -148,7 +148,7 @@ func TestInitGenesis_PoolsBalanceMismatch(t *testing.T) { Jailed: false, Tokens: math.NewInt(10), DelegatorShares: math.LegacyNewDecFromInt(math.NewInt(10)), - Description: types.NewDescription("bloop", "", "", "", ""), + Description: types.NewDescription("bloop", "", "", "", "", types.Metadata{}), } params := types.Params{ @@ -195,7 +195,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { validators[i], err = types.NewValidator( sdk.ValAddress(addrs[i]).String(), PKs[i], - types.NewDescription(fmt.Sprintf("#%d", i), "", "", "", ""), + types.NewDescription(fmt.Sprintf("#%d", i), "", "", "", "", types.Metadata{}), ) assert.NilError(t, err) validators[i].Status = types.Bonded diff --git a/tests/integration/staking/keeper/msg_server_test.go b/tests/integration/staking/keeper/msg_server_test.go index 7eb00bb97a97..f07308591a84 100644 --- a/tests/integration/staking/keeper/msg_server_test.go +++ b/tests/integration/staking/keeper/msg_server_test.go @@ -44,7 +44,7 @@ func TestCancelUnbondingDelegation(t *testing.T) { delegatorAddr := addrs[1] // setup a new validator with bonded status - validator, err := types.NewValidator(valAddr.String(), PKs[0], types.NewDescription("Validator", "", "", "", "")) + validator, err := types.NewValidator(valAddr.String(), PKs[0], types.NewDescription("Validator", "", "", "", "", types.Metadata{})) validator.Status = types.Bonded assert.NilError(t, err) assert.NilError(t, f.stakingKeeper.SetValidator(ctx, validator)) diff --git a/tests/integration/tx/aminojson/aminojson_test.go b/tests/integration/tx/aminojson/aminojson_test.go index ec218ca47da3..c17e845fe596 100644 --- a/tests/integration/tx/aminojson/aminojson_test.go +++ b/tests/integration/tx/aminojson/aminojson_test.go @@ -377,10 +377,12 @@ func TestAminoJSON_LegacyParity(t *testing.T) { "staking/create_validator": { gogo: &stakingtypes.MsgCreateValidator{Pubkey: pubkeyAny}, pulsar: &stakingapi.MsgCreateValidator{ - Pubkey: pubkeyAnyPulsar, - Description: &stakingapi.Description{}, - Commission: &stakingapi.CommissionRates{}, - Value: &v1beta1.Coin{}, + Pubkey: pubkeyAnyPulsar, + Description: &stakingapi.Description{ + Metadata: &stakingapi.Metadata{}, + }, + Commission: &stakingapi.CommissionRates{}, + Value: &v1beta1.Coin{}, }, }, "staking/msg_cancel_unbonding_delegation_response": { diff --git a/testutil/network/network.go b/testutil/network/network.go index bfdedb23e358..2bc85a10bd52 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -493,7 +493,7 @@ func New(l Logger, baseDir string, cfg Config) (NetworkI, error) { sdk.ValAddress(addr).String(), valPubKeys[i], sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens), - stakingtypes.NewDescription(nodeDirName, "", "", "", ""), + stakingtypes.NewDescription(nodeDirName, "", "", "", "", stakingtypes.Metadata{}), stakingtypes.NewCommissionRates(commission, sdkmath.LegacyOneDec(), sdkmath.LegacyOneDec()), sdkmath.OneInt(), ) diff --git a/x/auth/vesting/types/vesting.pb.go b/x/auth/vesting/types/vesting.pb.go index c5c2a54a8295..86bedb042b1c 100644 --- a/x/auth/vesting/types/vesting.pb.go +++ b/x/auth/vesting/types/vesting.pb.go @@ -4,11 +4,11 @@ package types import ( - types "github.com/cosmos/cosmos-sdk/x/auth/types" fmt "fmt" github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types1 "github.com/cosmos/cosmos-sdk/types" _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + types "github.com/cosmos/cosmos-sdk/x/auth/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" diff --git a/x/genutil/gentx_test.go b/x/genutil/gentx_test.go index 10721c819e12..d93199ce2e6c 100644 --- a/x/genutil/gentx_test.go +++ b/x/genutil/gentx_test.go @@ -36,7 +36,7 @@ var ( pk2 = priv2.PubKey() addr1 = sdk.AccAddress(pk1.Address()) addr2 = sdk.AccAddress(pk2.Address()) - desc = stakingtypes.NewDescription("testname", "", "", "", "") + desc = stakingtypes.NewDescription("testname", "", "", "", "", stakingtypes.Metadata{}) comm = stakingtypes.CommissionRates{} ) diff --git a/x/genutil/types/genesis_state_test.go b/x/genutil/types/genesis_state_test.go index b5741bef7f81..9e04d9a5f571 100644 --- a/x/genutil/types/genesis_state_test.go +++ b/x/genutil/types/genesis_state_test.go @@ -39,7 +39,7 @@ func TestNetGenesisState(t *testing.T) { } func TestValidateGenesisMultipleMessages(t *testing.T) { - desc := stakingtypes.NewDescription("testname", "", "", "", "") + desc := stakingtypes.NewDescription("testname", "", "", "", "", stakingtypes.Metadata{}) comm := stakingtypes.CommissionRates{} valAc := codectestutil.CodecOptions{}.GetValidatorCodec() @@ -66,7 +66,7 @@ func TestValidateGenesisMultipleMessages(t *testing.T) { } func TestValidateGenesisBadMessage(t *testing.T) { - desc := stakingtypes.NewDescription("testname", "", "", "", "") + desc := stakingtypes.NewDescription("testname", "", "", "", "", stakingtypes.Metadata{}) pk1Addr, err := codectestutil.CodecOptions{}.GetValidatorCodec().BytesToString(pk1.Address()) require.NoError(t, err) msg1 := stakingtypes.NewMsgEditValidator(pk1Addr, desc, nil, nil) diff --git a/x/staking/CHANGELOG.md b/x/staking/CHANGELOG.md index b185542abed4..24843a45f121 100644 --- a/x/staking/CHANGELOG.md +++ b/x/staking/CHANGELOG.md @@ -34,6 +34,9 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#19537](https://github.com/cosmos/cosmos-sdk/pull/19537) Changing `MinCommissionRate` in `MsgUpdateParams` now updates the minimum commission rate for all validators. * [#20434](https://github.com/cosmos/cosmos-sdk/pull/20434) Add consensus address to validator query response +* [#21315](https://github.com/cosmos/cosmos-sdk/pull/21315) Create metadata type and add metadata field in validator details proto + * Add parsing of `metadata-profile-pic-uri` in `create-validator` JSON. + * Add cli flag: `metadata-profile-pic-uri` to `edit-validator` cmd. ### Improvements @@ -42,6 +45,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#19277](https://github.com/cosmos/cosmos-sdk/pull/19277) Hooks calls on `SetUnbondingDelegationEntry`, `SetRedelegationEntry`, `Slash` and `RemoveValidator` returns errors instead of logging just like other hooks calls. * [#18636](https://github.com/cosmos/cosmos-sdk/pull/18636) `IterateBondedValidatorsByPower`, `GetDelegatorBonded`, `Delegate`, `Unbond`, `Slash`, `Jail`, `SlashRedelegation`, `ApplyAndReturnValidatorSetUpdates` methods no longer panics on any kind of errors but instead returns appropriate errors. * [#18506](https://github.com/cosmos/cosmos-sdk/pull/18506) Detect the length of the ed25519 pubkey in CreateValidator to prevent panic. +* [#21315](https://github.com/cosmos/cosmos-sdk/pull/21315) Add a `Validate` method to the `Description` type that validates the metadata as well as other description details. ### API Breaking Changes @@ -96,8 +100,11 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#17335](https://github.com/cosmos/cosmos-sdk/pull/17335) Remove usage of `"cosmossdk.io/x/staking/types".Infraction_*` in favour of `"cosmossdk.io/api/cosmos/staking/v1beta1".Infraction_` in order to remove dependency between modules on staking * [#20295](https://github.com/cosmos/cosmos-sdk/pull/20295) `GetValidatorByConsAddr` now returns the Cosmos SDK `cryptotypes.Pubkey` instead of `cometcrypto.Publickey`. The caller is responsible to translate the returned value to the expected type. * Remove `CmtConsPublicKey()` and `TmConsPublicKey()` from `Validator` interface and as methods on the `Validator` struct. -* [#21480](https://github.com/cosmos/cosmos-sdk/pull/21480) ConsensusKeeper is required to be passed to the keeper. - +* [#21480](https://github.com/cosmos/cosmos-sdk/pull/21480) ConsensusKeeper is required to be passed to the keeper. +* [#21315](https://github.com/cosmos/cosmos-sdk/pull/21315) New struct `Metadata` to store extra validator information. + * New field `Metadata` introduced in `types`: `Description`. + * The signature of `NewDescription` has changed to accept an extra argument of type `Metadata`. + ### State Breaking changes * [#18841](https://github.com/cosmos/cosmos-sdk/pull/18841) In a undelegation or redelegation if the shares being left delegated correspond to less than 1 token (in base denom) the entire delegation gets removed. diff --git a/x/staking/client/cli/flags.go b/x/staking/client/cli/flags.go index 61643a04865f..45f3a65e8f38 100644 --- a/x/staking/client/cli/flags.go +++ b/x/staking/client/cli/flags.go @@ -15,12 +15,14 @@ const ( FlagSharesAmount = "shares-amount" FlagSharesFraction = "shares-fraction" - FlagMoniker = "moniker" - FlagEditMoniker = "new-moniker" - FlagIdentity = "identity" - FlagWebsite = "website" - FlagSecurityContact = "security-contact" - FlagDetails = "details" + FlagMoniker = "moniker" + FlagEditMoniker = "new-moniker" + FlagIdentity = "identity" + FlagWebsite = "website" + FlagSecurityContact = "security-contact" + FlagDetails = "details" + FlagMetadataProfilePicUri = "metadata-profile-pic-uri" + FlagMetadataSocialHandleUris = "metadata-social-handle-uris" FlagCommissionRate = "commission-rate" FlagCommissionMaxRate = "commission-max-rate" @@ -89,6 +91,8 @@ func flagSetDescriptionEdit() *flag.FlagSet { fs.String(FlagWebsite, types.DoNotModifyDesc, "The validator's (optional) website") fs.String(FlagSecurityContact, types.DoNotModifyDesc, "The validator's (optional) security contact email") fs.String(FlagDetails, types.DoNotModifyDesc, "The validator's (optional) details") + fs.String(FlagMetadataProfilePicUri, "", "The validator's profile pic uri") + fs.StringArray(FlagMetadataSocialHandleUris, []string{}, "The validator's social handles uris") return fs } diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 3e80b30a047b..0e1ba1c396dd 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -72,6 +72,7 @@ Where validator.json contains: "website": "validator's (optional) website", "security": "validator's (optional) security contact email", "details": "validator's (optional) details", + "metadata-profile-pic-uri": "link to validator's (optional) profile picture", "commission-rate": "0.1", "commission-max-rate": "0.2", "commission-max-change-rate": "0.01", @@ -129,7 +130,15 @@ func NewEditValidatorCmd() *cobra.Command { website, _ := cmd.Flags().GetString(FlagWebsite) security, _ := cmd.Flags().GetString(FlagSecurityContact) details, _ := cmd.Flags().GetString(FlagDetails) - description := types.NewDescription(moniker, identity, website, security, details) + profilePicUri, _ := cmd.Flags().GetString(FlagMetadataProfilePicUri) + socialHandlesUris, _ := cmd.Flags().GetStringArray(FlagMetadataSocialHandleUris) + + metadata := types.Metadata{ + ProfilePicUri: profilePicUri, + SocialHandleUris: socialHandlesUris, + } + + description := types.NewDescription(moniker, identity, website, security, details, metadata) var newRate *math.LegacyDec @@ -183,6 +192,7 @@ func newBuildCreateValidatorMsg(clientCtx client.Context, txf tx.Factory, fs *fl val.Website, val.Security, val.Details, + val.Metadata, ) valStr, err := valAc.BytesToString(sdk.ValAddress(valAddr)) @@ -225,6 +235,8 @@ func CreateValidatorMsgFlagSet(ipDefault string) (fs *flag.FlagSet, defaultsDesc fsCreateValidator.String(FlagSecurityContact, "", "The validator's (optional) security contact email") fsCreateValidator.String(FlagDetails, "", "The validator's (optional) details") fsCreateValidator.String(FlagIdentity, "", "The (optional) identity signature (ex. UPort or Keybase)") + fsCreateValidator.String(FlagMetadataProfilePicUri, "", "The validator's profile pic uri") + fsCreateValidator.StringArray(FlagMetadataSocialHandleUris, []string{}, "The validator's social handles uris") fsCreateValidator.AddFlagSet(FlagSetCommissionCreate()) fsCreateValidator.AddFlagSet(FlagSetMinSelfDelegation()) fsCreateValidator.AddFlagSet(FlagSetAmount()) @@ -263,6 +275,7 @@ type TxCreateValidatorConfig struct { SecurityContact string Details string Identity string + Metadata types.Metadata } func PrepareConfigForTxCreateValidator(flagSet *flag.FlagSet, moniker, nodeID, chainID string, valPubKey cryptotypes.PubKey) (TxCreateValidatorConfig, error) { @@ -302,6 +315,14 @@ func PrepareConfigForTxCreateValidator(flagSet *flag.FlagSet, moniker, nodeID, c return c, err } + profilePicUri, err := flagSet.GetString(FlagMetadataProfilePicUri) + if err != nil { + return c, err + } + metadata := types.Metadata{ + ProfilePicUri: profilePicUri, + } + c.Amount, err = flagSet.GetString(FlagAmount) if err != nil { return c, err @@ -338,6 +359,7 @@ func PrepareConfigForTxCreateValidator(flagSet *flag.FlagSet, moniker, nodeID, c c.SecurityContact = securityContact c.Details = details c.Identity = identity + c.Metadata = metadata c.ChainID = chainID c.Moniker = moniker @@ -379,6 +401,7 @@ func BuildCreateValidatorMsg(clientCtx client.Context, config TxCreateValidatorC config.Website, config.SecurityContact, config.Details, + config.Metadata, ) // get the initial validator commission parameters diff --git a/x/staking/client/cli/utils.go b/x/staking/client/cli/utils.go index ff22b8876fc4..fc4ed032efc4 100644 --- a/x/staking/client/cli/utils.go +++ b/x/staking/client/cli/utils.go @@ -24,23 +24,26 @@ type validator struct { Website string Security string Details string + Metadata types.Metadata CommissionRates types.CommissionRates MinSelfDelegation math.Int } func parseAndValidateValidatorJSON(cdc codec.Codec, path string) (validator, error) { type internalVal struct { - Amount string `json:"amount"` - PubKey json.RawMessage `json:"pubkey"` - Moniker string `json:"moniker"` - Identity string `json:"identity,omitempty"` - Website string `json:"website,omitempty"` - Security string `json:"security,omitempty"` - Details string `json:"details,omitempty"` - CommissionRate string `json:"commission-rate"` - CommissionMaxRate string `json:"commission-max-rate"` - CommissionMaxChange string `json:"commission-max-change-rate"` - MinSelfDelegation string `json:"min-self-delegation"` + Amount string `json:"amount"` + PubKey json.RawMessage `json:"pubkey"` + Moniker string `json:"moniker"` + Identity string `json:"identity,omitempty"` + Website string `json:"website,omitempty"` + Security string `json:"security,omitempty"` + Details string `json:"details,omitempty"` + MetadataProfilePicUri string `json:"metadata-profile-pic-uri,omitempty"` + MetadataSocialHandlesUris []string `json:"metadata-social-handles-uris,omitempty"` + CommissionRate string `json:"commission-rate"` + CommissionMaxRate string `json:"commission-max-rate"` + CommissionMaxChange string `json:"commission-max-change-rate"` + MinSelfDelegation string `json:"min-self-delegation"` } contents, err := os.ReadFile(path) @@ -87,6 +90,11 @@ func parseAndValidateValidatorJSON(cdc codec.Codec, path string) (validator, err return validator{}, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "minimum self delegation must be a positive integer") } + metadata, err := buildMetadata(v.MetadataProfilePicUri, v.MetadataSocialHandlesUris) + if err != nil { + return validator{}, err + } + return validator{ Amount: amount, PubKey: pk, @@ -95,6 +103,7 @@ func parseAndValidateValidatorJSON(cdc codec.Codec, path string) (validator, err Website: v.Website, Security: v.Security, Details: v.Details, + Metadata: metadata, CommissionRates: commissionRates, MinSelfDelegation: minSelfDelegation, }, nil @@ -124,3 +133,12 @@ func buildCommissionRates(rateStr, maxRateStr, maxChangeRateStr string) (commiss return commission, nil } + +func buildMetadata(profilePicUri string, socialHandlesUris []string) (metadata types.Metadata, err error) { + metadata.ProfilePicUri = profilePicUri + metadata.SocialHandleUris = socialHandlesUris + if err := metadata.Validate(); err != nil { + return metadata, err + } + return metadata, nil +} diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index 92561bc6e7f3..24e0f1bd7437 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -481,7 +481,7 @@ func (s *KeeperTestSuite) TestValidatorsMigrationToColls() { // legacy Set method s.ctx.KVStore(s.key).Set(getValidatorKey(valAddrs[i]), valBz) }, - "d8acdcf8b7c8e17f3e83f0a4c293f89ad619a5dcb14d232911ccc5da15653177", + "55565aebbb67e1de08d0f17634ad168c68eae74f5cc9074e3a1ec4d1fbff16e5", ) s.Require().NoError(err) @@ -507,7 +507,7 @@ func (s *KeeperTestSuite) TestValidatorsMigrationToColls() { err := s.stakingKeeper.SetValidator(s.ctx, val) s.Require().NoError(err) }, - "d8acdcf8b7c8e17f3e83f0a4c293f89ad619a5dcb14d232911ccc5da15653177", + "55565aebbb67e1de08d0f17634ad168c68eae74f5cc9074e3a1ec4d1fbff16e5", ) s.Require().NoError(err) } diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index d40816eb61a8..272932c494fb 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -109,7 +109,7 @@ func (k msgServer) CreateValidator(ctx context.Context, msg *types.MsgCreateVali ) } - if _, err := msg.Description.EnsureLength(); err != nil { + if _, err := msg.Description.Validate(); err != nil { return nil, err } @@ -176,7 +176,7 @@ func (k msgServer) EditValidator(ctx context.Context, msg *types.MsgEditValidato return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid validator address: %s", err) } - if msg.Description == (types.Description{}) { + if msg.Description.IsEmpty() { return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "empty description") } diff --git a/x/staking/proto/buf.lock b/x/staking/proto/buf.lock index 3a2b87c1a666..3ad9de72f05b 100644 --- a/x/staking/proto/buf.lock +++ b/x/staking/proto/buf.lock @@ -11,6 +11,11 @@ deps: repository: cosmos-proto commit: 04467658e59e44bbb22fe568206e1f70 digest: shake256:73a640bd60e0c523b0f8237ff34eab67c45a38b64bbbde1d80224819d272dbf316ac183526bd245f994af6608b025f5130483d0133c5edd385531326b5990466 + - remote: buf.build + owner: cosmos + repository: cosmos-sdk + commit: 05419252bcc241ea8023acf1ed4cadc5 + digest: shake256:1e54a48c19a8b59d35e0a7efa76402939f515f2d8005df099856f24c37c20a52800308f025abb8cffcd014d437b49707388aaca4865d9d063d8f25d5d4eb77d5 - remote: buf.build owner: cosmos repository: gogo-proto @@ -19,5 +24,15 @@ deps: - remote: buf.build owner: googleapis repository: googleapis - commit: 7e6f6e774e29406da95bd61cdcdbc8bc - digest: shake256:fe43dd2265ea0c07d76bd925eeba612667cf4c948d2ce53d6e367e1b4b3cb5fa69a51e6acb1a6a50d32f894f054a35e6c0406f6808a483f2752e10c866ffbf73 + commit: 8bc2c51e08c447cd8886cdea48a73e14 + digest: shake256:a969155953a5cedc5b2df5b42c368f2bc66ff8ce1804bc96e0f14ff2ee8a893687963058909df844d1643cdbc98ff099d2daa6bc9f9f5b8886c49afdc60e19af + - remote: buf.build + owner: protocolbuffers + repository: wellknowntypes + commit: 657250e6a39648cbb169d079a60bd9ba + digest: shake256:00de25001b8dd2e29d85fc4bcc3ede7aed886d76d67f5e0f7a9b320b90f871d3eb73507d50818d823a0512f3f8db77a11c043685528403e31ff3fef18323a9fb + - remote: buf.build + owner: tendermint + repository: tendermint + commit: 33ed361a90514289beabf3189e1d7665 + digest: shake256:038267e06294714fd883610626554b04a127b576b4e253befb4206cb72d5d3c1eeccacd4b9ec8e3fb891f7c14e1cb0f770c077d2989638995b0a61c85afedb1d diff --git a/x/staking/proto/cosmos/staking/v1beta1/staking.proto b/x/staking/proto/cosmos/staking/v1beta1/staking.proto index 8b8709322305..b6dd5fcbff78 100644 --- a/x/staking/proto/cosmos/staking/v1beta1/staking.proto +++ b/x/staking/proto/cosmos/staking/v1beta1/staking.proto @@ -1,17 +1,16 @@ syntax = "proto3"; package cosmos.staking.v1beta1; +import "amino/amino.proto"; +import "cometbft/abci/v1/types.proto"; +import "cometbft/types/v1/types.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; -import "cosmos_proto/cosmos.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "amino/amino.proto"; -import "cometbft/types/v1/types.proto"; -import "cometbft/abci/v1/types.proto"; - option go_package = "cosmossdk.io/x/staking/types"; // HistoricalInfo contains header and validator information for a given block. @@ -79,6 +78,19 @@ message Description { string security_contact = 4; // details define other optional details. string details = 5; + // metadata defines extra information about the validator. + Metadata metadata = 6 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; +} + +// Metadata defines extra information about the validator. +message Metadata { + option (gogoproto.equal) = true; + + // profile_pic_uri defines a link to the validator profile picture. + string profile_pic_uri = 1; + + // social_handle_uris defines a string array of uris to the validator's social handles. + repeated string social_handle_uris = 2; } // Validator defines a validator, together with the total amount of the @@ -221,7 +233,8 @@ message UnbondingDelegation { string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.ValidatorAddressString"]; // entries are the unbonding delegation entries. repeated UnbondingDelegationEntry entries = 3 - [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // unbonding delegation entries + [(gogoproto.nullable) = false, + (amino.dont_omitempty) = true]; // unbonding delegation entries } // UnbondingDelegationEntry defines an unbonding object with relevant metadata. @@ -294,7 +307,8 @@ message Redelegation { string validator_dst_address = 3 [(cosmos_proto.scalar) = "cosmos.ValidatorAddressString"]; // entries are the redelegation entries. repeated RedelegationEntry entries = 4 - [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; // redelegation entries + [(gogoproto.nullable) = false, + (amino.dont_omitempty) = true]; // redelegation entries } // Params defines the parameters for the x/staking module. diff --git a/x/staking/simulation/msg_factory.go b/x/staking/simulation/msg_factory.go index 31c35cddd507..49aff2505298 100644 --- a/x/staking/simulation/msg_factory.go +++ b/x/staking/simulation/msg_factory.go @@ -39,12 +39,17 @@ func MsgCreateValidatorFactory(k *keeper.Keeper) simsx.SimMsgFactoryFn[*types.Ms } selfDelegation := valOper.LiquidBalance().RandSubsetCoin(reporter, bondDenom) + description := types.NewDescription( r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10), + types.Metadata{ + ProfilePicUri: RandURIOfHostLength(r.Rand, 10), + SocialHandleUris: RandSocialHandleURIs(r.Rand, 2, 10), + }, ) maxCommission := math.LegacyNewDecWithPrec(int64(r.IntInRange(0, 100)), 2) @@ -138,7 +143,10 @@ func MsgEditValidatorFactory(k *keeper.Keeper) simsx.SimMsgFactoryFn[*types.MsgE } valOpAddrBz := must(k.ValidatorAddressCodec().StringToBytes(val.GetOperator())) valOper := testData.GetAccountbyAccAddr(reporter, valOpAddrBz) - d := types.NewDescription(r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10)) + d := types.NewDescription(r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10), r.StringN(10), types.Metadata{ + ProfilePicUri: RandURIOfHostLength(r.Rand, 10), + SocialHandleUris: RandSocialHandleURIs(r.Rand, 2, 10), + }) msg := types.NewMsgEditValidator(val.GetOperator(), d, &newCommissionRate, nil) return []simsx.SimAccount{valOper}, msg diff --git a/x/staking/simulation/rand_util.go b/x/staking/simulation/rand_util.go new file mode 100644 index 000000000000..c847a66f788f --- /dev/null +++ b/x/staking/simulation/rand_util.go @@ -0,0 +1,36 @@ +package simulation + +import ( + "fmt" + "math/rand" + "net/url" + + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" +) + +// RandURIOfHostLength returns a random valid uri with hostname length n. If n = 0, returns an empty string. +func RandURIOfHostLength(r *rand.Rand, n int) string { + if n == 0 { + return "" + } + tld := ".com" + hostLength := n - len(tld) + uri := &url.URL{ + Scheme: "https", + Host: fmt.Sprintf("%s%s", simtypes.RandStringOfLength(r, hostLength), tld), + } + + return uri.String() +} + +// RandSocialHandleURIs returns a string array of length num with uris. +func RandSocialHandleURIs(r *rand.Rand, num, uriHostLength int) []string { + if num == 0 { + return []string{} + } + var socialHandles []string + for i := 0; i < num; i++ { + socialHandles = append(socialHandles, RandURIOfHostLength(r, uriHostLength)) + } + return socialHandles +} diff --git a/x/staking/simulation/rand_util_test.go b/x/staking/simulation/rand_util_test.go new file mode 100644 index 000000000000..fb619e784eee --- /dev/null +++ b/x/staking/simulation/rand_util_test.go @@ -0,0 +1,60 @@ +package simulation_test + +import ( + "math/rand" + "net/url" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "cosmossdk.io/x/staking/simulation" +) + +func TestRandURIOfHostLength(t *testing.T) { + t.Parallel() + r := rand.New(rand.NewSource(time.Now().Unix())) + tests := []struct { + name string + n int + want int + }{ + {"0-size", 0, 0}, + {"10-size", 10, 10}, + {"1_000_000-size", 1_000_000, 1_000_000}, + } + for _, tt := range tests { + tc := tt + t.Run(tc.name, func(t *testing.T) { + got := 0 + uri := simulation.RandURIOfHostLength(r, tc.n) + if uri != "" { + parsedUri, err := url.Parse(uri) + require.NoError(t, err) + got = len(parsedUri.Host) + } + require.Equal(t, tc.want, got) + }) + } +} + +func TestRandSocialHandleURIs(t *testing.T) { + t.Parallel() + r := rand.New(rand.NewSource(time.Now().Unix())) + tests := []struct { + name string + n int + want int + }{ + {"0-handles", 0, 0}, + {"10-handles", 10, 10}, + {"100-handles", 100, 100}, + } + for _, tt := range tests { + tc := tt + t.Run(tc.name, func(t *testing.T) { + uris := simulation.RandSocialHandleURIs(r, tc.n, 10) + require.Equal(t, tc.want, len(uris)) + }) + } +} diff --git a/x/staking/types/msg.go b/x/staking/types/msg.go index b68818275ddf..879d3c821540 100644 --- a/x/staking/types/msg.go +++ b/x/staking/types/msg.go @@ -64,7 +64,7 @@ func (msg MsgCreateValidator) Validate(ac address.Codec) error { return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "invalid delegation amount") } - if msg.Description == (Description{}) { + if msg.Description.IsEmpty() { return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "empty description") } diff --git a/x/staking/types/staking.pb.go b/x/staking/types/staking.pb.go index d6511264f7c3..197e937a35d4 100644 --- a/x/staking/types/staking.pb.go +++ b/x/staking/types/staking.pb.go @@ -270,6 +270,8 @@ type Description struct { SecurityContact string `protobuf:"bytes,4,opt,name=security_contact,json=securityContact,proto3" json:"security_contact,omitempty"` // details define other optional details. Details string `protobuf:"bytes,5,opt,name=details,proto3" json:"details,omitempty"` + // metadata defines extra information about the validator. + Metadata Metadata `protobuf:"bytes,6,opt,name=metadata,proto3" json:"metadata"` } func (m *Description) Reset() { *m = Description{} } @@ -340,6 +342,68 @@ func (m *Description) GetDetails() string { return "" } +func (m *Description) GetMetadata() Metadata { + if m != nil { + return m.Metadata + } + return Metadata{} +} + +// Metadata defines extra information about the validator. +type Metadata struct { + // profile_pic_uri defines a link to the validator profile picture. + ProfilePicUri string `protobuf:"bytes,1,opt,name=profile_pic_uri,json=profilePicUri,proto3" json:"profile_pic_uri,omitempty"` + // social_handle_uris defines a string array of uris to the validator's social handles. + SocialHandleUris []string `protobuf:"bytes,2,rep,name=social_handle_uris,json=socialHandleUris,proto3" json:"social_handle_uris,omitempty"` +} + +func (m *Metadata) Reset() { *m = Metadata{} } +func (m *Metadata) String() string { return proto.CompactTextString(m) } +func (*Metadata) ProtoMessage() {} +func (*Metadata) Descriptor() ([]byte, []int) { + return fileDescriptor_64c30c6cf92913c9, []int{4} +} +func (m *Metadata) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Metadata.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Metadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_Metadata.Merge(m, src) +} +func (m *Metadata) XXX_Size() int { + return m.Size() +} +func (m *Metadata) XXX_DiscardUnknown() { + xxx_messageInfo_Metadata.DiscardUnknown(m) +} + +var xxx_messageInfo_Metadata proto.InternalMessageInfo + +func (m *Metadata) GetProfilePicUri() string { + if m != nil { + return m.ProfilePicUri + } + return "" +} + +func (m *Metadata) GetSocialHandleUris() []string { + if m != nil { + return m.SocialHandleUris + } + return nil +} + // Validator defines a validator, together with the total amount of the // Validator's bond shares and their exchange rate to coins. Slashing results in // a decrease in the exchange rate, allowing correct calculation of future @@ -381,7 +445,7 @@ func (m *Validator) Reset() { *m = Validator{} } func (m *Validator) String() string { return proto.CompactTextString(m) } func (*Validator) ProtoMessage() {} func (*Validator) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{4} + return fileDescriptor_64c30c6cf92913c9, []int{5} } func (m *Validator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -419,7 +483,7 @@ func (m *ValAddresses) Reset() { *m = ValAddresses{} } func (m *ValAddresses) String() string { return proto.CompactTextString(m) } func (*ValAddresses) ProtoMessage() {} func (*ValAddresses) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{5} + return fileDescriptor_64c30c6cf92913c9, []int{6} } func (m *ValAddresses) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -467,7 +531,7 @@ func (m *DVPair) Reset() { *m = DVPair{} } func (m *DVPair) String() string { return proto.CompactTextString(m) } func (*DVPair) ProtoMessage() {} func (*DVPair) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{6} + return fileDescriptor_64c30c6cf92913c9, []int{7} } func (m *DVPair) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -505,7 +569,7 @@ func (m *DVPairs) Reset() { *m = DVPairs{} } func (m *DVPairs) String() string { return proto.CompactTextString(m) } func (*DVPairs) ProtoMessage() {} func (*DVPairs) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{7} + return fileDescriptor_64c30c6cf92913c9, []int{8} } func (m *DVPairs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -555,7 +619,7 @@ func (m *DVVTriplet) Reset() { *m = DVVTriplet{} } func (m *DVVTriplet) String() string { return proto.CompactTextString(m) } func (*DVVTriplet) ProtoMessage() {} func (*DVVTriplet) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{8} + return fileDescriptor_64c30c6cf92913c9, []int{9} } func (m *DVVTriplet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -593,7 +657,7 @@ func (m *DVVTriplets) Reset() { *m = DVVTriplets{} } func (m *DVVTriplets) String() string { return proto.CompactTextString(m) } func (*DVVTriplets) ProtoMessage() {} func (*DVVTriplets) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{9} + return fileDescriptor_64c30c6cf92913c9, []int{10} } func (m *DVVTriplets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -645,7 +709,7 @@ func (m *Delegation) Reset() { *m = Delegation{} } func (m *Delegation) String() string { return proto.CompactTextString(m) } func (*Delegation) ProtoMessage() {} func (*Delegation) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{10} + return fileDescriptor_64c30c6cf92913c9, []int{11} } func (m *Delegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -689,7 +753,7 @@ func (m *UnbondingDelegation) Reset() { *m = UnbondingDelegation{} } func (m *UnbondingDelegation) String() string { return proto.CompactTextString(m) } func (*UnbondingDelegation) ProtoMessage() {} func (*UnbondingDelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{11} + return fileDescriptor_64c30c6cf92913c9, []int{12} } func (m *UnbondingDelegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -738,7 +802,7 @@ func (m *UnbondingDelegationEntry) Reset() { *m = UnbondingDelegationEnt func (m *UnbondingDelegationEntry) String() string { return proto.CompactTextString(m) } func (*UnbondingDelegationEntry) ProtoMessage() {} func (*UnbondingDelegationEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{12} + return fileDescriptor_64c30c6cf92913c9, []int{13} } func (m *UnbondingDelegationEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -815,7 +879,7 @@ func (m *RedelegationEntry) Reset() { *m = RedelegationEntry{} } func (m *RedelegationEntry) String() string { return proto.CompactTextString(m) } func (*RedelegationEntry) ProtoMessage() {} func (*RedelegationEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{13} + return fileDescriptor_64c30c6cf92913c9, []int{14} } func (m *RedelegationEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -889,7 +953,7 @@ func (m *Redelegation) Reset() { *m = Redelegation{} } func (m *Redelegation) String() string { return proto.CompactTextString(m) } func (*Redelegation) ProtoMessage() {} func (*Redelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{14} + return fileDescriptor_64c30c6cf92913c9, []int{15} } func (m *Redelegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -941,7 +1005,7 @@ func (m *Params) Reset() { *m = Params{} } func (m *Params) String() string { return proto.CompactTextString(m) } func (*Params) ProtoMessage() {} func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{15} + return fileDescriptor_64c30c6cf92913c9, []int{16} } func (m *Params) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1024,7 +1088,7 @@ func (m *DelegationResponse) Reset() { *m = DelegationResponse{} } func (m *DelegationResponse) String() string { return proto.CompactTextString(m) } func (*DelegationResponse) ProtoMessage() {} func (*DelegationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{16} + return fileDescriptor_64c30c6cf92913c9, []int{17} } func (m *DelegationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1079,7 +1143,7 @@ func (m *RedelegationEntryResponse) Reset() { *m = RedelegationEntryResp func (m *RedelegationEntryResponse) String() string { return proto.CompactTextString(m) } func (*RedelegationEntryResponse) ProtoMessage() {} func (*RedelegationEntryResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{17} + return fileDescriptor_64c30c6cf92913c9, []int{18} } func (m *RedelegationEntryResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1127,7 +1191,7 @@ func (m *RedelegationResponse) Reset() { *m = RedelegationResponse{} } func (m *RedelegationResponse) String() string { return proto.CompactTextString(m) } func (*RedelegationResponse) ProtoMessage() {} func (*RedelegationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{18} + return fileDescriptor_64c30c6cf92913c9, []int{19} } func (m *RedelegationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1181,7 +1245,7 @@ func (m *Pool) Reset() { *m = Pool{} } func (m *Pool) String() string { return proto.CompactTextString(m) } func (*Pool) ProtoMessage() {} func (*Pool) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{19} + return fileDescriptor_64c30c6cf92913c9, []int{20} } func (m *Pool) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1222,7 +1286,7 @@ func (m *ValidatorUpdates) Reset() { *m = ValidatorUpdates{} } func (m *ValidatorUpdates) String() string { return proto.CompactTextString(m) } func (*ValidatorUpdates) ProtoMessage() {} func (*ValidatorUpdates) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{20} + return fileDescriptor_64c30c6cf92913c9, []int{21} } func (m *ValidatorUpdates) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1276,7 +1340,7 @@ func (m *ConsPubKeyRotationHistory) Reset() { *m = ConsPubKeyRotationHis func (m *ConsPubKeyRotationHistory) String() string { return proto.CompactTextString(m) } func (*ConsPubKeyRotationHistory) ProtoMessage() {} func (*ConsPubKeyRotationHistory) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{21} + return fileDescriptor_64c30c6cf92913c9, []int{22} } func (m *ConsPubKeyRotationHistory) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1315,7 +1379,7 @@ func (m *ValAddrsOfRotatedConsKeys) Reset() { *m = ValAddrsOfRotatedCons func (m *ValAddrsOfRotatedConsKeys) String() string { return proto.CompactTextString(m) } func (*ValAddrsOfRotatedConsKeys) ProtoMessage() {} func (*ValAddrsOfRotatedConsKeys) Descriptor() ([]byte, []int) { - return fileDescriptor_64c30c6cf92913c9, []int{22} + return fileDescriptor_64c30c6cf92913c9, []int{23} } func (m *ValAddrsOfRotatedConsKeys) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1358,6 +1422,7 @@ func init() { proto.RegisterType((*CommissionRates)(nil), "cosmos.staking.v1beta1.CommissionRates") proto.RegisterType((*Commission)(nil), "cosmos.staking.v1beta1.Commission") proto.RegisterType((*Description)(nil), "cosmos.staking.v1beta1.Description") + proto.RegisterType((*Metadata)(nil), "cosmos.staking.v1beta1.Metadata") proto.RegisterType((*Validator)(nil), "cosmos.staking.v1beta1.Validator") proto.RegisterType((*ValAddresses)(nil), "cosmos.staking.v1beta1.ValAddresses") proto.RegisterType((*DVPair)(nil), "cosmos.staking.v1beta1.DVPair") @@ -1384,137 +1449,142 @@ func init() { } var fileDescriptor_64c30c6cf92913c9 = []byte{ - // 2065 bytes of a gzipped FileDescriptorProto + // 2146 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x59, 0x4b, 0x6c, 0x1b, 0xc7, - 0x19, 0xd6, 0x92, 0x0c, 0x25, 0xfd, 0x94, 0x44, 0x6a, 0xfc, 0xa2, 0xe8, 0x58, 0x92, 0x19, 0xb7, - 0x91, 0xdd, 0x9a, 0x8a, 0xdc, 0xc2, 0x05, 0x84, 0x20, 0x85, 0x29, 0xd2, 0x31, 0xf3, 0x90, 0xd4, - 0xa5, 0xa4, 0x3e, 0xd0, 0x66, 0x31, 0xdc, 0x1d, 0x52, 0x5b, 0x91, 0xb3, 0xec, 0xce, 0x50, 0x36, - 0xef, 0x3d, 0x04, 0x2e, 0x0a, 0xe4, 0x54, 0x04, 0x28, 0x8c, 0x1a, 0xe8, 0x25, 0xbd, 0xe5, 0x60, - 0xf4, 0xde, 0x5b, 0x5a, 0xa0, 0x80, 0xe1, 0x53, 0x11, 0xa0, 0x6e, 0x61, 0x1f, 0x12, 0x34, 0x97, - 0xa2, 0xa7, 0x1e, 0x8b, 0x79, 0xec, 0x83, 0xa2, 0x68, 0x59, 0x72, 0x50, 0x04, 0xed, 0x45, 0xe0, - 0xcc, 0xfc, 0xff, 0xb7, 0xf3, 0x7f, 0xf3, 0x3f, 0x66, 0x7e, 0xc1, 0x25, 0xdb, 0x63, 0x1d, 0x8f, - 0x2d, 0x33, 0x8e, 0xf7, 0x5c, 0xda, 0x5a, 0xde, 0x5f, 0x69, 0x10, 0x8e, 0x57, 0x82, 0x71, 0xa9, - 0xeb, 0x7b, 0xdc, 0x43, 0x67, 0x95, 0x54, 0x29, 0x98, 0xd5, 0x52, 0x85, 0xd3, 0x2d, 0xaf, 0xe5, - 0x49, 0x91, 0x65, 0xf1, 0x4b, 0x49, 0x17, 0xe6, 0x5a, 0x9e, 0xd7, 0x6a, 0x93, 0x65, 0x39, 0x6a, - 0xf4, 0x9a, 0xcb, 0x98, 0xf6, 0xf5, 0xd2, 0xfc, 0xc1, 0x25, 0xa7, 0xe7, 0x63, 0xee, 0x7a, 0x54, - 0xaf, 0x2f, 0x1c, 0x5c, 0xe7, 0x6e, 0x87, 0x30, 0x8e, 0x3b, 0xdd, 0x00, 0x5b, 0xed, 0xc4, 0x52, - 0x1f, 0xd5, 0xdb, 0xd2, 0xd8, 0xda, 0x94, 0x06, 0x66, 0x24, 0xb4, 0xc3, 0xf6, 0xdc, 0x00, 0x7b, - 0x16, 0x77, 0x5c, 0xea, 0x2d, 0xcb, 0xbf, 0x7a, 0xea, 0x82, 0xed, 0x75, 0x08, 0x6f, 0x34, 0xf9, - 0x32, 0xef, 0x77, 0x09, 0x5b, 0xde, 0x5f, 0x51, 0x3f, 0xf4, 0xf2, 0xcb, 0xe1, 0x32, 0x6e, 0xd8, - 0xee, 0x81, 0xd5, 0xe2, 0x87, 0x06, 0xcc, 0xdc, 0x72, 0x19, 0xf7, 0x7c, 0xd7, 0xc6, 0xed, 0x1a, - 0x6d, 0x7a, 0xe8, 0x75, 0x48, 0xef, 0x12, 0xec, 0x10, 0x3f, 0x6f, 0x2c, 0x1a, 0x4b, 0x99, 0x6b, - 0x73, 0xa5, 0x00, 0xa1, 0xa4, 0x34, 0xf7, 0x57, 0x4a, 0xb7, 0xa4, 0x40, 0x79, 0xf2, 0x93, 0xc7, - 0x0b, 0x63, 0x1f, 0x7d, 0xf6, 0xf1, 0x15, 0xc3, 0xd4, 0x3a, 0xa8, 0x02, 0xe9, 0x7d, 0xdc, 0x66, - 0x84, 0xe7, 0x13, 0x8b, 0xc9, 0xa5, 0xcc, 0xb5, 0x8b, 0xa5, 0xc3, 0x69, 0x2f, 0xed, 0xe0, 0xb6, - 0xeb, 0x60, 0xee, 0x0d, 0xa2, 0x28, 0xdd, 0xd5, 0x44, 0xde, 0x28, 0xfe, 0x2a, 0x01, 0xd9, 0x35, - 0xaf, 0xd3, 0x71, 0x19, 0x73, 0x3d, 0x6a, 0x62, 0x4e, 0x18, 0x7a, 0x0b, 0x52, 0x3e, 0xe6, 0x44, - 0xee, 0x6c, 0xb2, 0x7c, 0x5d, 0x28, 0x7e, 0xfa, 0x78, 0xe1, 0xbc, 0xfa, 0x04, 0x73, 0xf6, 0x4a, - 0xae, 0xb7, 0xdc, 0xc1, 0x7c, 0xb7, 0xf4, 0x0e, 0x69, 0x61, 0xbb, 0x5f, 0x21, 0xf6, 0xa3, 0x07, - 0x57, 0x41, 0xef, 0xa0, 0x42, 0x6c, 0xf5, 0x15, 0x89, 0x81, 0xbe, 0x07, 0x13, 0x1d, 0x7c, 0xc7, - 0x92, 0x78, 0x89, 0x17, 0xc2, 0x1b, 0xef, 0xe0, 0x3b, 0x62, 0x7f, 0xe8, 0x3d, 0xc8, 0x0a, 0x48, - 0x7b, 0x17, 0xd3, 0x16, 0x51, 0xc8, 0xc9, 0x17, 0x42, 0x9e, 0xee, 0xe0, 0x3b, 0x6b, 0x12, 0x4d, - 0xe0, 0xaf, 0xa6, 0x3e, 0xbf, 0xbf, 0x60, 0x14, 0xff, 0x60, 0x00, 0x44, 0xc4, 0x20, 0x0c, 0x39, - 0x3b, 0x1c, 0xc9, 0x8f, 0x32, 0x7d, 0x72, 0xaf, 0x8e, 0xe2, 0xfe, 0x00, 0xad, 0xe5, 0x69, 0xb1, - 0xbd, 0x87, 0x8f, 0x17, 0x0c, 0xf5, 0xd5, 0xac, 0x3d, 0x44, 0x7b, 0xa6, 0xd7, 0x75, 0x30, 0x27, - 0x96, 0x70, 0x65, 0xc9, 0x56, 0xe6, 0x5a, 0xa1, 0xa4, 0xfc, 0xbc, 0x14, 0xf8, 0x79, 0x69, 0x2b, - 0xf0, 0x73, 0x05, 0xf8, 0xc1, 0xdf, 0x02, 0x40, 0x50, 0xda, 0x62, 0x5d, 0xdb, 0xf0, 0x91, 0x01, - 0x99, 0x0a, 0x61, 0xb6, 0xef, 0x76, 0x45, 0xe4, 0xa0, 0x3c, 0x8c, 0x77, 0x3c, 0xea, 0xee, 0x69, - 0xaf, 0x9b, 0x34, 0x83, 0x21, 0x2a, 0xc0, 0x84, 0xeb, 0x10, 0xca, 0x5d, 0xde, 0x57, 0xc7, 0x64, - 0x86, 0x63, 0xa1, 0x75, 0x9b, 0x34, 0x98, 0x1b, 0xf0, 0x6c, 0x06, 0x43, 0x74, 0x19, 0x72, 0x8c, - 0xd8, 0x3d, 0xdf, 0xe5, 0x7d, 0xcb, 0xf6, 0x28, 0xc7, 0x36, 0xcf, 0xa7, 0xa4, 0x48, 0x36, 0x98, - 0x5f, 0x53, 0xd3, 0x02, 0xc4, 0x21, 0x1c, 0xbb, 0x6d, 0x96, 0x7f, 0x49, 0x81, 0xe8, 0xa1, 0xde, - 0xea, 0xbd, 0x71, 0x98, 0x0c, 0x9d, 0x15, 0xad, 0x41, 0xce, 0xeb, 0x12, 0x5f, 0xfc, 0xb6, 0xb0, - 0xe3, 0xf8, 0x84, 0x31, 0xed, 0x8d, 0xf9, 0x47, 0x0f, 0xae, 0x9e, 0xd6, 0x84, 0xdf, 0x50, 0x2b, - 0x75, 0xee, 0xbb, 0xb4, 0x65, 0x66, 0x03, 0x0d, 0x3d, 0x8d, 0x7e, 0x28, 0x8e, 0x8c, 0x32, 0x42, - 0x59, 0x8f, 0x59, 0xdd, 0x5e, 0x63, 0x8f, 0xf4, 0x35, 0xa9, 0xa7, 0x87, 0x48, 0xbd, 0x41, 0xfb, - 0xe5, 0xfc, 0x9f, 0x22, 0x68, 0xdb, 0xef, 0x77, 0xb9, 0x57, 0xda, 0xec, 0x35, 0xde, 0x26, 0x7d, - 0x71, 0x54, 0x1a, 0x67, 0x53, 0xc2, 0xa0, 0xb3, 0x90, 0xfe, 0x29, 0x76, 0xdb, 0xc4, 0x91, 0x8c, - 0x4c, 0x98, 0x7a, 0x84, 0x56, 0x21, 0xcd, 0x38, 0xe6, 0x3d, 0x26, 0x69, 0x98, 0xb9, 0x56, 0x1c, - 0xe5, 0x1b, 0x65, 0x8f, 0x3a, 0x75, 0x29, 0x69, 0x6a, 0x0d, 0xb4, 0x06, 0x69, 0xee, 0xed, 0x11, - 0xaa, 0x09, 0x2a, 0x7f, 0x43, 0x7b, 0xf3, 0x99, 0x61, 0x6f, 0xae, 0x51, 0x1e, 0xf3, 0xe3, 0x1a, - 0xe5, 0xa6, 0x56, 0x45, 0x3f, 0x86, 0x9c, 0x43, 0xda, 0xa4, 0x25, 0x99, 0x63, 0xbb, 0xd8, 0x27, - 0x2c, 0x9f, 0x96, 0x70, 0x2b, 0xc7, 0x0e, 0x0e, 0x33, 0x1b, 0x42, 0xd5, 0x25, 0x12, 0xda, 0x84, - 0x8c, 0x13, 0xb9, 0x53, 0x7e, 0x5c, 0x92, 0xf9, 0xca, 0x28, 0x1b, 0x63, 0x9e, 0x17, 0xcf, 0x3e, - 0x71, 0x08, 0xe1, 0x41, 0x3d, 0xda, 0xf0, 0xa8, 0xe3, 0xd2, 0x96, 0xb5, 0x4b, 0xdc, 0xd6, 0x2e, - 0xcf, 0x4f, 0x2c, 0x1a, 0x4b, 0x49, 0x33, 0x1b, 0xce, 0xdf, 0x92, 0xd3, 0x68, 0x13, 0x66, 0x22, - 0x51, 0x19, 0x21, 0x93, 0xc7, 0x8d, 0x90, 0xe9, 0x10, 0x40, 0x88, 0xa0, 0x77, 0x01, 0xa2, 0x18, - 0xcc, 0x83, 0x44, 0x2b, 0x1e, 0x1d, 0xcd, 0x71, 0x63, 0x62, 0x00, 0x88, 0xc2, 0xa9, 0x8e, 0x4b, - 0x2d, 0x46, 0xda, 0x4d, 0x4b, 0x33, 0x27, 0x70, 0x33, 0x92, 0xfe, 0x37, 0x8e, 0x71, 0x9a, 0x9f, - 0x3e, 0xb8, 0x9a, 0x55, 0xa3, 0xab, 0xcc, 0xd9, 0x5b, 0x7c, 0xad, 0xf4, 0xed, 0xef, 0x98, 0xb3, - 0x1d, 0x97, 0xd6, 0x49, 0xbb, 0x59, 0x09, 0x81, 0xd1, 0xeb, 0x70, 0x3e, 0x22, 0xc4, 0xa3, 0xd6, - 0xae, 0xd7, 0x76, 0x2c, 0x9f, 0x34, 0x2d, 0xdb, 0xeb, 0x51, 0x9e, 0x9f, 0x92, 0x34, 0x9e, 0x0b, - 0x45, 0x36, 0xe8, 0x2d, 0xaf, 0xed, 0x98, 0xa4, 0xb9, 0x26, 0x96, 0xd1, 0x2b, 0x10, 0xb1, 0x61, - 0xb9, 0x0e, 0xcb, 0x4f, 0x2f, 0x26, 0x97, 0x52, 0xe6, 0x54, 0x38, 0x59, 0x73, 0xd8, 0xea, 0xc4, - 0xfb, 0xf7, 0x17, 0xc6, 0x3e, 0xbf, 0xbf, 0x30, 0x56, 0xbc, 0x09, 0x53, 0x3b, 0xb8, 0xad, 0x43, - 0x8b, 0x30, 0x74, 0x1d, 0x26, 0x71, 0x30, 0xc8, 0x1b, 0x8b, 0xc9, 0x67, 0x86, 0x66, 0x24, 0x5a, - 0xfc, 0x9d, 0x01, 0xe9, 0xca, 0xce, 0x26, 0x76, 0x7d, 0x54, 0x85, 0xd9, 0xc8, 0x57, 0x9f, 0x37, - 0xca, 0x23, 0xf7, 0x0e, 0xc2, 0x7c, 0x1d, 0x66, 0xf7, 0x83, 0xc4, 0x11, 0xc2, 0xa8, 0x52, 0x73, - 0xf1, 0xd1, 0x83, 0xab, 0x17, 0x34, 0x4c, 0x98, 0x5c, 0x0e, 0xe0, 0xed, 0x1f, 0x98, 0x8f, 0xd9, - 0xfc, 0x16, 0x8c, 0xab, 0xad, 0x32, 0xf4, 0x5d, 0x78, 0xa9, 0x2b, 0x7e, 0x48, 0x53, 0x33, 0xd7, - 0xe6, 0x47, 0xfa, 0xbc, 0x94, 0x8f, 0x7b, 0x88, 0xd2, 0x2b, 0xfe, 0x22, 0x01, 0x50, 0xd9, 0xd9, - 0xd9, 0xf2, 0xdd, 0x6e, 0x9b, 0xf0, 0x2f, 0xcb, 0xf6, 0x6d, 0x38, 0x13, 0xd9, 0xce, 0x7c, 0xfb, - 0xf8, 0xf6, 0x9f, 0x0a, 0xf5, 0xeb, 0xbe, 0x7d, 0x28, 0xac, 0xc3, 0x78, 0x08, 0x9b, 0x3c, 0x3e, - 0x6c, 0x85, 0xf1, 0x61, 0x66, 0x7f, 0x00, 0x99, 0x88, 0x0c, 0x86, 0x6a, 0x30, 0xc1, 0xf5, 0x6f, - 0x4d, 0x70, 0x71, 0x34, 0xc1, 0x81, 0x5a, 0x9c, 0xe4, 0x50, 0xbd, 0xf8, 0x6f, 0x03, 0x20, 0x16, - 0x23, 0x5f, 0x4d, 0x1f, 0x43, 0x35, 0x48, 0xeb, 0xe4, 0x9c, 0x3c, 0x69, 0x72, 0xd6, 0x00, 0x31, - 0x52, 0x7f, 0x99, 0x80, 0x53, 0xdb, 0x41, 0xf4, 0x7e, 0xf5, 0x39, 0xd8, 0x86, 0x71, 0x42, 0xb9, - 0xef, 0x4a, 0x12, 0xc4, 0x99, 0xbf, 0x36, 0xea, 0xcc, 0x0f, 0x31, 0xaa, 0x4a, 0xb9, 0xdf, 0x8f, - 0x7b, 0x40, 0x80, 0x15, 0xe3, 0xe3, 0xd7, 0x49, 0xc8, 0x8f, 0x52, 0x45, 0xaf, 0x42, 0xd6, 0xf6, - 0x89, 0x9c, 0x08, 0xea, 0x8e, 0x21, 0x13, 0xe6, 0x4c, 0x30, 0xad, 0xcb, 0x8e, 0x09, 0xe2, 0xa2, - 0x26, 0x9c, 0x4b, 0x88, 0x9e, 0xec, 0x66, 0x36, 0x13, 0x21, 0xc8, 0xc2, 0xb3, 0x05, 0x59, 0x97, - 0xba, 0xdc, 0xc5, 0x6d, 0xab, 0x81, 0xdb, 0x98, 0xda, 0xc1, 0x0d, 0xf6, 0x58, 0x35, 0x7f, 0x46, - 0x63, 0x94, 0x15, 0x04, 0xaa, 0xc2, 0x78, 0x80, 0x96, 0x3a, 0x3e, 0x5a, 0xa0, 0x8b, 0x2e, 0xc2, - 0x54, 0xbc, 0x30, 0xc8, 0xdb, 0x48, 0xca, 0xcc, 0xc4, 0xea, 0xc2, 0x51, 0x95, 0x27, 0xfd, 0xcc, - 0xca, 0xa3, 0x2f, 0x7c, 0xbf, 0x49, 0xc2, 0xac, 0x49, 0x9c, 0xff, 0xfd, 0x63, 0xd9, 0x04, 0x50, - 0xa1, 0x2a, 0x32, 0xa9, 0x3e, 0x99, 0x13, 0xc4, 0xfb, 0xa4, 0x02, 0xa9, 0x30, 0xfe, 0xdf, 0x3a, - 0xa1, 0xbf, 0x26, 0x60, 0x2a, 0x7e, 0x42, 0xff, 0x97, 0x45, 0x0b, 0xad, 0x47, 0x69, 0x2a, 0x25, - 0xd3, 0xd4, 0xe5, 0x51, 0x69, 0x6a, 0xc8, 0x9b, 0x8f, 0xc8, 0x4f, 0x5f, 0x24, 0x21, 0xbd, 0x89, - 0x7d, 0xdc, 0x61, 0x68, 0x63, 0xe8, 0x6e, 0x1b, 0x74, 0x05, 0x0e, 0x3a, 0x73, 0x45, 0x77, 0x41, - 0x94, 0x2f, 0x7f, 0x38, 0xea, 0x6a, 0xfb, 0x35, 0x98, 0x11, 0x6f, 0xe4, 0xd0, 0x20, 0x45, 0xee, - 0xb4, 0x7c, 0xea, 0x86, 0xd6, 0x33, 0xb4, 0x00, 0x19, 0x21, 0x16, 0xe5, 0x61, 0x21, 0x03, 0x1d, - 0x7c, 0xa7, 0xaa, 0x66, 0xd0, 0x0a, 0xa0, 0xdd, 0xb0, 0x71, 0x61, 0x45, 0x44, 0x18, 0x4b, 0xd3, - 0xe5, 0x44, 0xde, 0x30, 0x67, 0xa3, 0xd5, 0x40, 0xe5, 0x02, 0x80, 0xd8, 0x89, 0xe5, 0x10, 0xea, - 0x75, 0xf4, 0x63, 0x6f, 0x52, 0xcc, 0x54, 0xc4, 0x04, 0xfa, 0xb9, 0xa1, 0xae, 0xc9, 0x07, 0x5e, - 0xd3, 0xfa, 0x95, 0xb2, 0xf5, 0x1c, 0x81, 0xf1, 0xaf, 0xc7, 0x0b, 0x85, 0x3e, 0xee, 0xb4, 0x57, - 0x8b, 0x87, 0xe0, 0x14, 0x0f, 0x7b, 0xe0, 0x8b, 0xcb, 0xf3, 0xe0, 0x6b, 0x1c, 0xd5, 0x20, 0xb7, - 0x47, 0xfa, 0x96, 0xef, 0x71, 0x95, 0x6c, 0x9a, 0x84, 0xe8, 0xf7, 0xcc, 0x5c, 0x70, 0xbe, 0x0d, - 0xcc, 0x48, 0xec, 0xfa, 0xef, 0xd2, 0x72, 0x4a, 0xec, 0xce, 0x9c, 0xd9, 0x23, 0x7d, 0x53, 0xeb, - 0xdd, 0x24, 0x64, 0xf5, 0x92, 0x88, 0x96, 0xbb, 0x9f, 0x7d, 0x7c, 0xe5, 0x7c, 0x74, 0x69, 0x5f, - 0xbe, 0x13, 0xf6, 0xc9, 0xd4, 0x11, 0x8b, 0x8b, 0x2f, 0x8a, 0x8a, 0x90, 0x49, 0x58, 0x57, 0xbc, - 0x29, 0xc5, 0x1b, 0x24, 0xf6, 0x56, 0x30, 0x9e, 0xfd, 0x06, 0x89, 0xf4, 0x07, 0xde, 0x20, 0xb1, - 0x10, 0x7d, 0x23, 0xaa, 0x01, 0x89, 0xa3, 0xac, 0x89, 0x7b, 0xa7, 0x56, 0x92, 0x91, 0x3f, 0x56, - 0xfc, 0xb3, 0x01, 0x73, 0x43, 0xde, 0x1c, 0x6e, 0xd9, 0x06, 0xe4, 0xc7, 0x16, 0xa5, 0x57, 0xf4, - 0xf5, 0xd6, 0x4f, 0x16, 0x1c, 0xb3, 0xfe, 0x50, 0x21, 0xf8, 0x72, 0x8a, 0x99, 0xce, 0x64, 0x7f, - 0x34, 0xe0, 0x74, 0x7c, 0x03, 0xa1, 0x29, 0x75, 0x98, 0x8a, 0x7f, 0x5a, 0x1b, 0x71, 0xe9, 0x79, - 0x8c, 0x88, 0xef, 0x7f, 0x00, 0x04, 0xed, 0x44, 0x19, 0x43, 0x75, 0xe7, 0x56, 0x9e, 0x9b, 0x94, - 0x60, 0x63, 0x87, 0x66, 0x0e, 0x75, 0x36, 0x5f, 0x18, 0x90, 0xda, 0xf4, 0xbc, 0x36, 0xfa, 0x19, - 0xcc, 0x52, 0x8f, 0x5b, 0x22, 0xb2, 0x88, 0x63, 0xe9, 0xd6, 0x81, 0xca, 0xc6, 0xd5, 0x67, 0x72, - 0xf5, 0x8f, 0xc7, 0x0b, 0xc3, 0x9a, 0x83, 0x04, 0xea, 0x0e, 0x15, 0xf5, 0x78, 0x59, 0x0a, 0x6d, - 0xa9, 0xee, 0x42, 0x13, 0xa6, 0x07, 0x3f, 0xa7, 0x32, 0xf6, 0x8d, 0xa3, 0x3e, 0x37, 0x7d, 0xe4, - 0xa7, 0xa6, 0x1a, 0xb1, 0xef, 0xac, 0x4e, 0x88, 0x53, 0xfb, 0xa7, 0x38, 0xb9, 0xf7, 0x20, 0x17, - 0xa6, 0xab, 0x6d, 0xd9, 0xde, 0x62, 0xe8, 0x26, 0x8c, 0xab, 0x4e, 0x57, 0xf0, 0x58, 0xb8, 0x18, - 0xf5, 0x4e, 0x71, 0xc3, 0x76, 0x4b, 0xfb, 0xb1, 0xbe, 0xa7, 0x52, 0x1a, 0xe0, 0x53, 0x2b, 0xcb, - 0xf6, 0xe7, 0xc3, 0x04, 0xcc, 0xad, 0x79, 0x94, 0xe9, 0x46, 0x8f, 0x8e, 0x6a, 0xd5, 0xab, 0xed, - 0xa3, 0xcb, 0x23, 0xda, 0x50, 0x53, 0xc3, 0xcd, 0xa6, 0x1d, 0xc8, 0x8a, 0x12, 0x6b, 0x7b, 0xf4, - 0x05, 0x7b, 0x4d, 0xd3, 0x5e, 0xdb, 0xd1, 0x3b, 0xda, 0x23, 0x7d, 0x81, 0x4b, 0xc9, 0xed, 0x01, - 0xdc, 0xe4, 0xc9, 0x70, 0x29, 0xb9, 0x1d, 0xc3, 0x3d, 0x0b, 0x69, 0x7d, 0xbf, 0x4a, 0xc9, 0xdb, - 0x83, 0x1e, 0xa1, 0xeb, 0x90, 0x14, 0xa9, 0xf0, 0xa5, 0x63, 0x24, 0x0f, 0xa1, 0x10, 0x2b, 0x6b, - 0x75, 0x98, 0xd3, 0x9d, 0x02, 0xb6, 0xd1, 0x94, 0x8c, 0x12, 0x69, 0xd0, 0xdb, 0xa4, 0x7f, 0x48, - 0xdb, 0x60, 0xea, 0xb9, 0xda, 0x06, 0x57, 0x7e, 0x6f, 0x00, 0x44, 0x3d, 0x33, 0xf4, 0x4d, 0x38, - 0x57, 0xde, 0x58, 0xaf, 0x58, 0xf5, 0xad, 0x1b, 0x5b, 0xdb, 0x75, 0x6b, 0x7b, 0xbd, 0xbe, 0x59, - 0x5d, 0xab, 0xdd, 0xac, 0x55, 0x2b, 0xb9, 0xb1, 0x42, 0xf6, 0xee, 0xbd, 0xc5, 0xcc, 0x36, 0x65, - 0x5d, 0x62, 0xbb, 0x4d, 0x97, 0x38, 0xe8, 0xeb, 0x70, 0x7a, 0x50, 0x5a, 0x8c, 0xaa, 0x95, 0x9c, - 0x51, 0x98, 0xba, 0x7b, 0x6f, 0x71, 0x42, 0xbd, 0x11, 0x88, 0x83, 0x96, 0xe0, 0xcc, 0xb0, 0x5c, - 0x6d, 0xfd, 0xcd, 0x5c, 0xa2, 0x30, 0x7d, 0xf7, 0xde, 0xe2, 0x64, 0xf8, 0x98, 0x40, 0x45, 0x40, - 0x71, 0x49, 0x8d, 0x97, 0x2c, 0xc0, 0xdd, 0x7b, 0x8b, 0x69, 0x15, 0x32, 0x85, 0xd4, 0xfb, 0xbf, - 0x9d, 0x1f, 0xbb, 0xf2, 0x13, 0x80, 0x1a, 0x6d, 0xfa, 0xd8, 0x96, 0xa9, 0xa1, 0x00, 0x67, 0x6b, - 0xeb, 0x37, 0xcd, 0x1b, 0x6b, 0x5b, 0xb5, 0x8d, 0xf5, 0xc1, 0x6d, 0x1f, 0x58, 0xab, 0x6c, 0x6c, - 0x97, 0xdf, 0xa9, 0x5a, 0xf5, 0xda, 0x9b, 0xeb, 0x39, 0x03, 0x9d, 0x83, 0x53, 0x03, 0x6b, 0xdf, - 0x5f, 0xdf, 0xaa, 0xbd, 0x5b, 0xcd, 0x25, 0xca, 0xd7, 0x3f, 0x79, 0x32, 0x6f, 0x3c, 0x7c, 0x32, - 0x6f, 0xfc, 0xfd, 0xc9, 0xbc, 0xf1, 0xc1, 0xd3, 0xf9, 0xb1, 0x87, 0x4f, 0xe7, 0xc7, 0xfe, 0xf2, - 0x74, 0x7e, 0xec, 0x47, 0x2f, 0x0f, 0x04, 0x63, 0x54, 0x8e, 0xe4, 0x7f, 0x17, 0x1a, 0x69, 0xe9, - 0x35, 0xdf, 0xfa, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf4, 0xd1, 0x83, 0x1f, 0xd5, 0x19, 0x00, - 0x00, + 0x19, 0xd6, 0x92, 0x34, 0x25, 0xfe, 0x14, 0x45, 0x6a, 0xfc, 0xa2, 0xe8, 0x58, 0x92, 0x19, 0x37, + 0x91, 0xdd, 0x98, 0x8c, 0xdc, 0xc2, 0x05, 0x84, 0x20, 0x85, 0x29, 0xca, 0x36, 0x93, 0x58, 0x52, + 0x97, 0xa2, 0xfa, 0x40, 0x9b, 0xc5, 0x70, 0x77, 0x48, 0x6d, 0x45, 0xee, 0xb2, 0x3b, 0x43, 0xd9, + 0xbc, 0xf7, 0x10, 0xb8, 0x28, 0x90, 0x53, 0x11, 0xa0, 0x30, 0x6a, 0xa0, 0x97, 0xf6, 0x96, 0x83, + 0xd1, 0x7b, 0x6f, 0x69, 0x81, 0x02, 0x86, 0x4f, 0x45, 0x80, 0xba, 0x85, 0x7d, 0x48, 0xd0, 0x5c, + 0xda, 0x9e, 0x7a, 0x2c, 0xe6, 0xb1, 0x0f, 0x8a, 0xa2, 0x65, 0xc9, 0x41, 0x11, 0xb4, 0x17, 0x62, + 0x67, 0xe6, 0xff, 0xbf, 0x99, 0xff, 0x3d, 0xf3, 0x13, 0x2e, 0x9a, 0x2e, 0xed, 0xba, 0xb4, 0x4c, + 0x19, 0xde, 0xb5, 0x9d, 0x76, 0x79, 0x6f, 0xb9, 0x49, 0x18, 0x5e, 0xf6, 0xc7, 0xa5, 0x9e, 0xe7, + 0x32, 0x17, 0x9d, 0x91, 0x54, 0x25, 0x7f, 0x56, 0x51, 0x15, 0x66, 0x71, 0xd7, 0x76, 0xdc, 0xb2, + 0xf8, 0x95, 0xa4, 0x85, 0x57, 0x4c, 0xb7, 0x4b, 0x58, 0xb3, 0xc5, 0xca, 0xb8, 0x69, 0xda, 0xe5, + 0xbd, 0xe5, 0x32, 0x1b, 0xf4, 0x08, 0x55, 0xab, 0xe7, 0x83, 0x55, 0x31, 0xbb, 0x7f, 0x79, 0x5e, + 0x9d, 0xa6, 0x89, 0x29, 0x09, 0x8e, 0x62, 0xba, 0xb6, 0xa3, 0xd6, 0xe7, 0xe4, 0xba, 0x21, 0x46, + 0x65, 0x75, 0x28, 0xb9, 0x74, 0xaa, 0xed, 0xb6, 0x5d, 0x39, 0xcf, 0xbf, 0x7c, 0x86, 0xb6, 0xeb, + 0xb6, 0x3b, 0xa4, 0x2c, 0x46, 0xcd, 0x7e, 0xab, 0x8c, 0x9d, 0x81, 0xbf, 0xd7, 0xfe, 0x25, 0xab, + 0xef, 0x61, 0x66, 0xbb, 0xfe, 0x5e, 0x0b, 0xfb, 0xd7, 0x99, 0xdd, 0x25, 0x94, 0xe1, 0x6e, 0x4f, + 0x12, 0x14, 0x3f, 0xd2, 0x60, 0xe6, 0x96, 0x4d, 0x99, 0xeb, 0xd9, 0x26, 0xee, 0xd4, 0x9c, 0x96, + 0x8b, 0xde, 0x82, 0xe4, 0x0e, 0xc1, 0x16, 0xf1, 0xf2, 0xda, 0xa2, 0xb6, 0x94, 0xbe, 0x3a, 0x57, + 0xf2, 0xe5, 0x2d, 0x49, 0x31, 0xf7, 0x96, 0x4b, 0xb7, 0x04, 0x41, 0x25, 0xf5, 0xc9, 0x93, 0x85, + 0x89, 0xdf, 0x7c, 0xf6, 0xf1, 0x65, 0x4d, 0x57, 0x3c, 0xa8, 0x0a, 0xc9, 0x3d, 0xdc, 0xa1, 0x84, + 0xe5, 0x63, 0x8b, 0xf1, 0xa5, 0xf4, 0xd5, 0x0b, 0xa5, 0x83, 0xd5, 0x5e, 0xda, 0xc6, 0x1d, 0xdb, + 0xc2, 0xcc, 0x1d, 0x46, 0x91, 0xbc, 0x2b, 0xb1, 0xbc, 0x56, 0xfc, 0x45, 0x0c, 0xb2, 0xab, 0x6e, + 0xb7, 0x6b, 0x53, 0x6a, 0xbb, 0x8e, 0x8e, 0x19, 0xa1, 0xe8, 0x1d, 0x48, 0x78, 0x98, 0x11, 0x71, + 0xb2, 0x54, 0xe5, 0x1a, 0x67, 0xfc, 0xf4, 0xc9, 0xc2, 0x39, 0xb9, 0x05, 0xb5, 0x76, 0x4b, 0xb6, + 0x5b, 0xee, 0x62, 0xb6, 0x53, 0x7a, 0x8f, 0xb4, 0xb1, 0x39, 0xa8, 0x12, 0xf3, 0xf1, 0xc3, 0x2b, + 0xa0, 0x4e, 0x50, 0x25, 0xa6, 0xdc, 0x45, 0x60, 0xa0, 0xef, 0xc0, 0x54, 0x17, 0xdf, 0x35, 0x04, + 0x5e, 0xec, 0xa5, 0xf0, 0x26, 0xbb, 0xf8, 0x2e, 0x3f, 0x1f, 0x7a, 0x1f, 0xb2, 0x1c, 0xd2, 0xdc, + 0xc1, 0x4e, 0x9b, 0x48, 0xe4, 0xf8, 0x4b, 0x21, 0x67, 0xba, 0xf8, 0xee, 0xaa, 0x40, 0xe3, 0xf8, + 0x2b, 0x89, 0xcf, 0x1f, 0x2c, 0x68, 0xc5, 0xdf, 0x6b, 0x00, 0xa1, 0x62, 0x10, 0x86, 0x9c, 0x19, + 0x8c, 0xc4, 0xa6, 0x54, 0x59, 0xee, 0xf5, 0x71, 0xba, 0xdf, 0xa7, 0xd6, 0x4a, 0x86, 0x1f, 0xef, + 0xd1, 0x93, 0x05, 0x4d, 0xee, 0x9a, 0x35, 0x47, 0xd4, 0x9e, 0xee, 0xf7, 0x2c, 0xcc, 0x88, 0xc1, + 0xfd, 0x47, 0x68, 0x2b, 0x7d, 0xb5, 0x50, 0x92, 0xce, 0x55, 0xf2, 0x9d, 0xab, 0xb4, 0xe5, 0x3b, + 0x97, 0x04, 0xfc, 0xf0, 0xaf, 0x3e, 0x20, 0x48, 0x6e, 0xbe, 0xae, 0x64, 0xf8, 0xa7, 0x06, 0xe9, + 0x2a, 0xa1, 0xa6, 0x67, 0xf7, 0xb8, 0xbb, 0xa2, 0x3c, 0x4c, 0x76, 0x5d, 0xc7, 0xde, 0x55, 0x5e, + 0x97, 0xd2, 0xfd, 0x21, 0x2a, 0xc0, 0x94, 0x6d, 0x11, 0x87, 0xd9, 0x6c, 0x20, 0xcd, 0xa4, 0x07, + 0x63, 0xce, 0x75, 0x87, 0x34, 0xa9, 0xed, 0xeb, 0x59, 0xf7, 0x87, 0xe8, 0x12, 0xe4, 0x28, 0x31, + 0xfb, 0x9e, 0xcd, 0x06, 0x86, 0xe9, 0x3a, 0x0c, 0x9b, 0x2c, 0x9f, 0x10, 0x24, 0x59, 0x7f, 0x7e, + 0x55, 0x4e, 0x73, 0x10, 0x8b, 0x30, 0x6c, 0x77, 0x68, 0xfe, 0x84, 0x04, 0x51, 0x43, 0x74, 0x13, + 0xa6, 0xba, 0x84, 0x61, 0x0b, 0x33, 0x9c, 0x4f, 0x0a, 0x99, 0x17, 0xc7, 0x69, 0xf4, 0xb6, 0xa2, + 0x8b, 0x3a, 0x73, 0xc0, 0xac, 0x64, 0x6e, 0xc1, 0x94, 0x4f, 0x86, 0x5e, 0x83, 0x6c, 0xcf, 0x73, + 0x5b, 0x76, 0x87, 0x18, 0x3d, 0xdb, 0x34, 0xfa, 0x9e, 0xad, 0xe4, 0xce, 0xa8, 0xe9, 0x4d, 0xdb, + 0x6c, 0x78, 0x36, 0x7a, 0x03, 0x10, 0x75, 0x4d, 0x1b, 0x77, 0x8c, 0x1d, 0xec, 0x58, 0x1d, 0xc2, + 0x29, 0xa9, 0x08, 0xad, 0x94, 0x9e, 0x93, 0x2b, 0xb7, 0xc4, 0x42, 0xc3, 0xb3, 0xa9, 0xda, 0xe7, + 0xfe, 0x24, 0xa4, 0x82, 0xe8, 0x42, 0xab, 0x90, 0x73, 0x7b, 0xc4, 0xe3, 0xdf, 0x06, 0xb6, 0x2c, + 0x8f, 0x50, 0xaa, 0xc2, 0x27, 0xff, 0xf8, 0xe1, 0x95, 0x53, 0x4a, 0x9e, 0xeb, 0x72, 0xa5, 0xce, + 0x3c, 0xdb, 0x69, 0xeb, 0x59, 0x9f, 0x43, 0x4d, 0xa3, 0xef, 0x73, 0x1f, 0x73, 0x28, 0x71, 0x68, + 0x9f, 0x1a, 0xbd, 0x7e, 0x73, 0x97, 0x0c, 0x94, 0x17, 0x9c, 0x1a, 0xf1, 0x82, 0xeb, 0xce, 0xa0, + 0x92, 0xff, 0x63, 0x08, 0x6d, 0x7a, 0x83, 0x1e, 0x73, 0x4b, 0x9b, 0xfd, 0xe6, 0xbb, 0x64, 0xc0, + 0x7d, 0x4b, 0xe1, 0x6c, 0x0a, 0x18, 0x74, 0x06, 0x92, 0x3f, 0xc6, 0x76, 0x87, 0x58, 0xc2, 0x84, + 0x53, 0xba, 0x1a, 0xa1, 0x15, 0x48, 0x52, 0x86, 0x59, 0x9f, 0x0a, 0xbb, 0xcd, 0x5c, 0x2d, 0x8e, + 0x53, 0x7d, 0xc5, 0x75, 0xac, 0xba, 0xa0, 0xd4, 0x15, 0x07, 0x5a, 0x85, 0x24, 0x73, 0x77, 0x89, + 0xa3, 0x2c, 0x5a, 0xf9, 0xba, 0x0a, 0xbf, 0xd3, 0xa3, 0xe1, 0x57, 0x73, 0x58, 0x24, 0xf0, 0x6a, + 0x0e, 0xd3, 0x15, 0x2b, 0xfa, 0x21, 0xe4, 0x2c, 0xd2, 0x21, 0x6d, 0xa1, 0x39, 0xba, 0x83, 0x3d, + 0x42, 0x85, 0x17, 0xa4, 0x2a, 0xcb, 0x47, 0x8e, 0x66, 0x3d, 0x1b, 0x40, 0xd5, 0x05, 0x12, 0xda, + 0x84, 0xb4, 0x15, 0xfa, 0x7f, 0x7e, 0x52, 0x28, 0xf3, 0xd5, 0x71, 0x32, 0x46, 0x42, 0x25, 0xea, + 0x61, 0x51, 0x08, 0xee, 0xf2, 0x7d, 0xa7, 0xe9, 0x3a, 0x96, 0xed, 0xb4, 0x8d, 0x1d, 0x62, 0xb7, + 0x77, 0x58, 0x7e, 0x6a, 0x51, 0x5b, 0x8a, 0xeb, 0xd9, 0x60, 0xfe, 0x96, 0x98, 0x46, 0x9b, 0x30, + 0x13, 0x92, 0x8a, 0x90, 0x4e, 0x1d, 0x35, 0xa4, 0x33, 0x01, 0x00, 0x27, 0x41, 0xb7, 0x01, 0xc2, + 0xa4, 0x91, 0x07, 0x81, 0x56, 0x3c, 0x3c, 0xfd, 0x44, 0x85, 0x89, 0x00, 0x20, 0x07, 0x4e, 0x76, + 0x6d, 0xc7, 0xa0, 0xa4, 0xd3, 0x32, 0x94, 0xe6, 0x38, 0x6e, 0x5a, 0xa8, 0xff, 0xed, 0x23, 0x58, + 0xf3, 0xd3, 0x87, 0x57, 0xb2, 0x72, 0x74, 0x85, 0x5a, 0xbb, 0x8b, 0x6f, 0x96, 0xbe, 0xf9, 0x2d, + 0x7d, 0xb6, 0x6b, 0x3b, 0x75, 0xd2, 0x69, 0x55, 0x03, 0x60, 0xf4, 0x16, 0x9c, 0x0b, 0x15, 0xe2, + 0x3a, 0xc6, 0x8e, 0xdb, 0xb1, 0x0c, 0x8f, 0xb4, 0x0c, 0xd3, 0xed, 0x3b, 0x2c, 0x3f, 0x2d, 0xd4, + 0x78, 0x36, 0x20, 0xd9, 0x70, 0x6e, 0xb9, 0x1d, 0x4b, 0x27, 0xad, 0x55, 0xbe, 0x8c, 0x5e, 0x85, + 0x50, 0x1b, 0x86, 0x6d, 0xd1, 0x7c, 0x66, 0x31, 0xbe, 0x94, 0xd0, 0xa7, 0x83, 0xc9, 0x9a, 0x45, + 0x57, 0xa6, 0x3e, 0x78, 0xb0, 0x30, 0xf1, 0xf9, 0x83, 0x85, 0x89, 0xe2, 0x0d, 0x98, 0xde, 0xc6, + 0x1d, 0x15, 0x5a, 0x84, 0xa2, 0x6b, 0x90, 0xc2, 0xfe, 0x20, 0xaf, 0xf1, 0xd0, 0x7e, 0x4e, 0x68, + 0x86, 0xa4, 0xc5, 0xdf, 0x6a, 0x90, 0xac, 0x6e, 0x6f, 0x62, 0xdb, 0x43, 0x6b, 0x30, 0x1b, 0xfa, + 0xea, 0x8b, 0x46, 0x79, 0xe8, 0xde, 0x7e, 0x98, 0xaf, 0xc3, 0xec, 0x9e, 0x9f, 0x38, 0x02, 0x18, + 0x59, 0x1b, 0x2f, 0x3c, 0x7e, 0x78, 0xe5, 0xbc, 0x82, 0x09, 0x92, 0xcb, 0x3e, 0xbc, 0xbd, 0x7d, + 0xf3, 0x11, 0x99, 0xdf, 0x81, 0x49, 0x79, 0x54, 0x8a, 0xbe, 0x0d, 0x27, 0x7a, 0xfc, 0x43, 0x88, + 0x9a, 0xbe, 0x3a, 0x3f, 0xd6, 0xe7, 0x05, 0x7d, 0xd4, 0x43, 0x24, 0x5f, 0xf1, 0x67, 0x31, 0x80, + 0xea, 0xf6, 0xf6, 0x96, 0x67, 0xf7, 0x3a, 0x84, 0x7d, 0x59, 0xb2, 0x37, 0xe0, 0x74, 0x28, 0x3b, + 0xf5, 0xcc, 0xa3, 0xcb, 0x7f, 0x32, 0xe0, 0xaf, 0x7b, 0xe6, 0x81, 0xb0, 0x16, 0x65, 0x01, 0x6c, + 0xfc, 0xe8, 0xb0, 0x55, 0xca, 0x46, 0x35, 0xfb, 0x3d, 0x48, 0x87, 0xca, 0xa0, 0xa8, 0x06, 0x53, + 0x4c, 0x7d, 0x2b, 0x05, 0x17, 0xc7, 0x2b, 0xd8, 0x67, 0x1b, 0xaa, 0x5a, 0x3e, 0x7b, 0xf1, 0xdf, + 0x1a, 0x40, 0x24, 0x46, 0xbe, 0x9a, 0x3e, 0x86, 0x6a, 0x90, 0x54, 0xc9, 0x39, 0x7e, 0xdc, 0xe4, + 0xac, 0x00, 0x22, 0x4a, 0xfd, 0x79, 0x0c, 0x4e, 0x36, 0xfc, 0xe8, 0xfd, 0xea, 0xeb, 0xa0, 0x01, + 0x93, 0xc4, 0x61, 0x9e, 0x2d, 0x94, 0xc0, 0x6d, 0xfe, 0xe6, 0x38, 0x9b, 0x1f, 0x20, 0xd4, 0x9a, + 0xc3, 0xbc, 0x41, 0xd4, 0x03, 0x7c, 0xac, 0x88, 0x3e, 0x7e, 0x19, 0x87, 0xfc, 0x38, 0x56, 0xf4, + 0x3a, 0x64, 0x4d, 0x8f, 0x88, 0x09, 0xbf, 0xee, 0x68, 0x22, 0x61, 0xce, 0xf8, 0xd3, 0xaa, 0xec, + 0xe8, 0xc0, 0x6f, 0x96, 0xdc, 0xb9, 0x38, 0xe9, 0xf1, 0xae, 0x92, 0x33, 0x21, 0x82, 0x28, 0x3c, + 0x5b, 0x90, 0xb5, 0x1d, 0x9b, 0xf1, 0x1b, 0x52, 0x13, 0x77, 0xb0, 0x63, 0xfa, 0x57, 0xee, 0x23, + 0xd5, 0xfc, 0x19, 0x85, 0x51, 0x91, 0x10, 0x68, 0x0d, 0x26, 0x7d, 0xb4, 0xc4, 0xd1, 0xd1, 0x7c, + 0x5e, 0x74, 0x01, 0xa6, 0xa3, 0x85, 0x41, 0xdc, 0x46, 0x12, 0x7a, 0x3a, 0x52, 0x17, 0x0e, 0xab, + 0x3c, 0xc9, 0xe7, 0x56, 0x1e, 0x75, 0xe1, 0xfb, 0x55, 0x1c, 0x66, 0x75, 0x62, 0xfd, 0xef, 0x9b, + 0x65, 0x13, 0x40, 0x86, 0x2a, 0xcf, 0xa4, 0xca, 0x32, 0xc7, 0x88, 0xf7, 0x94, 0x04, 0xa9, 0x52, + 0xf6, 0xdf, 0xb2, 0xd0, 0x5f, 0x62, 0x30, 0x1d, 0xb5, 0xd0, 0xff, 0x65, 0xd1, 0x42, 0xeb, 0x61, + 0x9a, 0x4a, 0x88, 0x34, 0x75, 0x69, 0x5c, 0x9a, 0x1a, 0xf1, 0xe6, 0x43, 0xf2, 0xd3, 0x17, 0x71, + 0x48, 0x6e, 0x62, 0x0f, 0x77, 0x29, 0xda, 0x18, 0xb9, 0xdb, 0xfa, 0x6d, 0x8c, 0xfd, 0xce, 0x5c, + 0x55, 0xbd, 0x12, 0xe9, 0xcb, 0x1f, 0x8d, 0xbb, 0xda, 0x7e, 0x0d, 0x66, 0xf8, 0xa3, 0x3e, 0x10, + 0x48, 0x2a, 0x37, 0x23, 0xde, 0xe6, 0x81, 0xf4, 0x14, 0x2d, 0x40, 0x9a, 0x93, 0x85, 0x79, 0x98, + 0xd3, 0x40, 0x17, 0xdf, 0x5d, 0x93, 0x33, 0x68, 0x19, 0xd0, 0x4e, 0xd0, 0x69, 0x31, 0x42, 0x45, + 0x68, 0x4b, 0x99, 0x4a, 0x2c, 0xaf, 0xe9, 0xb3, 0xe1, 0xaa, 0xcf, 0x72, 0x1e, 0x80, 0x9f, 0xc4, + 0xb0, 0x88, 0xe3, 0x76, 0xd5, 0xeb, 0x34, 0xc5, 0x67, 0xaa, 0x7c, 0x02, 0xfd, 0x54, 0x93, 0xd7, + 0xe4, 0x7d, 0xcf, 0x7f, 0xf5, 0x4a, 0xd9, 0x7a, 0x81, 0xc0, 0xf8, 0xd7, 0x93, 0x85, 0xc2, 0x00, + 0x77, 0x3b, 0x2b, 0xc5, 0x03, 0x70, 0x8a, 0x07, 0x75, 0x24, 0xf8, 0xe5, 0x79, 0xb8, 0x7d, 0x80, + 0x6a, 0x90, 0xdb, 0x25, 0x03, 0xc3, 0x73, 0x99, 0x4c, 0x36, 0x2d, 0x42, 0xd4, 0x7b, 0x66, 0xce, + 0xb7, 0x6f, 0x13, 0x53, 0x12, 0xb9, 0xfe, 0xdb, 0x4e, 0x25, 0xc1, 0x4f, 0xa7, 0xcf, 0xec, 0x92, + 0x81, 0xae, 0xf8, 0x6e, 0x10, 0xb2, 0x72, 0x91, 0x47, 0xcb, 0xbd, 0xcf, 0x3e, 0xbe, 0x7c, 0x2e, + 0xbc, 0xb4, 0x97, 0xef, 0x06, 0x8d, 0x3d, 0x69, 0x62, 0x7e, 0xf1, 0x45, 0x61, 0x11, 0xd2, 0x09, + 0xed, 0xf1, 0x37, 0x25, 0x7f, 0x83, 0x44, 0xde, 0x0a, 0xda, 0xf3, 0xdf, 0x20, 0x21, 0xff, 0xd0, + 0x1b, 0x24, 0x12, 0xa2, 0x6f, 0x87, 0x35, 0x20, 0x76, 0x98, 0x34, 0x51, 0xef, 0x54, 0x4c, 0x22, + 0xf2, 0x27, 0x8a, 0x7f, 0xd2, 0x60, 0x6e, 0xc4, 0x9b, 0x83, 0x23, 0x9b, 0x80, 0xbc, 0xc8, 0xa2, + 0xf0, 0x8a, 0x81, 0x3a, 0xfa, 0xf1, 0x82, 0x63, 0xd6, 0x1b, 0x29, 0x04, 0x5f, 0x4e, 0x31, 0x53, + 0x99, 0xec, 0x0f, 0x1a, 0x9c, 0x8a, 0x1e, 0x20, 0x10, 0xa5, 0x0e, 0xd3, 0xd1, 0xad, 0x95, 0x10, + 0x17, 0x5f, 0x44, 0x88, 0xe8, 0xf9, 0x87, 0x40, 0xd0, 0x76, 0x98, 0x31, 0x64, 0x3b, 0x71, 0xf9, + 0x85, 0x95, 0xe2, 0x1f, 0xec, 0xc0, 0xcc, 0x21, 0x6d, 0xf3, 0x85, 0x06, 0x89, 0x4d, 0xd7, 0xed, + 0xa0, 0x9f, 0xc0, 0xac, 0xe3, 0x32, 0x83, 0x47, 0x16, 0xb1, 0x0c, 0xd5, 0x3a, 0x90, 0xd9, 0x78, + 0xed, 0xb9, 0xba, 0xfa, 0xfb, 0x93, 0x85, 0x51, 0xce, 0x61, 0x05, 0xaa, 0x96, 0x9a, 0xe3, 0xb2, + 0x8a, 0x20, 0xda, 0x92, 0xdd, 0x85, 0x16, 0x64, 0x86, 0xb7, 0x93, 0x19, 0xfb, 0xfa, 0x61, 0xdb, + 0x65, 0x0e, 0xdd, 0x6a, 0xba, 0x19, 0xd9, 0x67, 0x65, 0x8a, 0x5b, 0xed, 0x1f, 0xdc, 0x72, 0xef, + 0x43, 0x2e, 0x48, 0x57, 0x0d, 0xd1, 0x8f, 0xa3, 0xe8, 0x06, 0x4c, 0xca, 0xd6, 0x9c, 0xff, 0x58, + 0xb8, 0x10, 0x36, 0x7b, 0x71, 0xd3, 0xb4, 0x4b, 0x7b, 0x91, 0x46, 0xad, 0x64, 0x1a, 0xd2, 0xa7, + 0x62, 0x16, 0xfd, 0xda, 0x47, 0x31, 0x98, 0x5b, 0x75, 0x1d, 0xaa, 0x1a, 0x3d, 0x2a, 0xaa, 0x65, + 0x73, 0x79, 0x80, 0x2e, 0x8d, 0x69, 0x43, 0x4d, 0x8f, 0x36, 0x9b, 0xb6, 0x21, 0xcb, 0x4b, 0xac, + 0xe9, 0x3a, 0x2f, 0xd9, 0x6b, 0xca, 0xb8, 0x1d, 0x4b, 0x9d, 0x68, 0x97, 0x0c, 0x38, 0xae, 0x43, + 0xee, 0x0c, 0xe1, 0xc6, 0x8f, 0x87, 0xeb, 0x90, 0x3b, 0x11, 0xdc, 0x33, 0x90, 0x54, 0xf7, 0xab, + 0x84, 0xb8, 0x3d, 0xa8, 0x11, 0xba, 0x06, 0x71, 0x9e, 0x0a, 0x4f, 0x1c, 0x21, 0x79, 0x70, 0x86, + 0x48, 0x59, 0xab, 0xc3, 0x9c, 0xea, 0x14, 0xd0, 0x8d, 0x96, 0xd0, 0x28, 0x11, 0x02, 0xbd, 0x4b, + 0x06, 0x07, 0xb4, 0x0d, 0xa6, 0x5f, 0xa8, 0x6d, 0x70, 0xf9, 0x77, 0x1a, 0x40, 0xd8, 0x33, 0x43, + 0x6f, 0xc0, 0xd9, 0xca, 0xc6, 0x7a, 0xd5, 0xa8, 0x6f, 0x5d, 0xdf, 0x6a, 0xd4, 0x8d, 0xc6, 0x7a, + 0x7d, 0x73, 0x6d, 0xb5, 0x76, 0xa3, 0xb6, 0x56, 0xcd, 0x4d, 0x14, 0xb2, 0xf7, 0xee, 0x2f, 0xa6, + 0x1b, 0x0e, 0xed, 0x11, 0xd3, 0x6e, 0xd9, 0xc4, 0x42, 0xaf, 0xc1, 0xa9, 0x61, 0x6a, 0x3e, 0x5a, + 0xab, 0xe6, 0xb4, 0xc2, 0xf4, 0xbd, 0xfb, 0x8b, 0x53, 0xf2, 0x8d, 0x40, 0x2c, 0xb4, 0x04, 0xa7, + 0x47, 0xe9, 0x6a, 0xeb, 0x37, 0x73, 0xb1, 0x42, 0xe6, 0xde, 0xfd, 0xc5, 0x54, 0xf0, 0x98, 0x40, + 0x45, 0x40, 0x51, 0x4a, 0x85, 0x17, 0x2f, 0xc0, 0xbd, 0xfb, 0x8b, 0x49, 0x19, 0x32, 0x85, 0xc4, + 0x07, 0xbf, 0x9e, 0x9f, 0xb8, 0xfc, 0x23, 0x80, 0x9a, 0xd3, 0xf2, 0xb0, 0x29, 0x52, 0x43, 0x01, + 0xce, 0xd4, 0xd6, 0x6f, 0xe8, 0xd7, 0x57, 0xb7, 0x6a, 0x1b, 0xeb, 0xc3, 0xc7, 0xde, 0xb7, 0x56, + 0xdd, 0x68, 0x54, 0xde, 0x5b, 0x33, 0xea, 0xb5, 0x9b, 0xeb, 0x39, 0x0d, 0x9d, 0x85, 0x93, 0x43, + 0x6b, 0xdf, 0x5d, 0xdf, 0xaa, 0xdd, 0x5e, 0xcb, 0xc5, 0x2a, 0xd7, 0x3e, 0x79, 0x3a, 0xaf, 0x3d, + 0x7a, 0x3a, 0xaf, 0xfd, 0xed, 0xe9, 0xbc, 0xf6, 0xe1, 0xb3, 0xf9, 0x89, 0x47, 0xcf, 0xe6, 0x27, + 0xfe, 0xfc, 0x6c, 0x7e, 0xe2, 0x07, 0xaf, 0x0c, 0x05, 0x63, 0x58, 0x8e, 0xc4, 0xdf, 0x21, 0xcd, + 0xa4, 0xf0, 0x9a, 0x6f, 0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0x85, 0x67, 0xcc, 0xc5, 0x86, 0x1a, + 0x00, 0x00, } func (this *Pool) Description() (desc *github_com_cosmos_gogoproto_protoc_gen_gogo_descriptor.FileDescriptorSet) { @@ -1523,743 +1593,750 @@ func (this *Pool) Description() (desc *github_com_cosmos_gogoproto_protoc_gen_go func StakingDescription() (desc *github_com_cosmos_gogoproto_protoc_gen_gogo_descriptor.FileDescriptorSet) { d := &github_com_cosmos_gogoproto_protoc_gen_gogo_descriptor.FileDescriptorSet{} var gzipped = []byte{ - // 11763 bytes of a gzipped FileDescriptorSet - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x7b, 0x90, 0x63, 0xd9, - 0x59, 0xdf, 0x5c, 0x49, 0xad, 0x96, 0x3e, 0x49, 0xad, 0xdb, 0xa7, 0x7b, 0x66, 0x34, 0x3d, 0xbb, - 0xd3, 0x3d, 0x77, 0x76, 0x77, 0x66, 0x67, 0x77, 0x7b, 0x76, 0x66, 0x67, 0x67, 0x77, 0xb5, 0x2f, - 0x24, 0xb5, 0x7a, 0x46, 0xb3, 0xfd, 0xf2, 0x95, 0xba, 0xbd, 0xbb, 0x3c, 0x2e, 0xb7, 0xaf, 0x4e, - 0x77, 0xdf, 0x1d, 0xe9, 0x5e, 0x59, 0xf7, 0x6a, 0xa6, 0x7b, 0x53, 0x95, 0x32, 0x01, 0x13, 0xb3, - 0x3c, 0x62, 0x02, 0x01, 0x63, 0x7b, 0x8c, 0x81, 0x80, 0x6d, 0x08, 0x04, 0x62, 0x43, 0x20, 0x54, - 0x1e, 0xa4, 0x12, 0x02, 0xa4, 0x42, 0x1c, 0xaa, 0x92, 0x50, 0x54, 0xb1, 0x01, 0x9b, 0x2a, 0x1c, - 0x6c, 0x08, 0x10, 0x9b, 0xa2, 0xe2, 0x4a, 0x2a, 0x75, 0x5e, 0xf7, 0x21, 0x5d, 0xb5, 0xd4, 0xb3, - 0xbb, 0xc6, 0x81, 0xfc, 0x33, 0xd3, 0xf7, 0x9c, 0xef, 0xfb, 0x9d, 0x73, 0xbe, 0xf3, 0x9d, 0xef, - 0x7c, 0xe7, 0x3b, 0x0f, 0xc1, 0xef, 0x2f, 0xc3, 0xc2, 0xae, 0x6d, 0xef, 0xb6, 0xf0, 0xa5, 0x4e, - 0xd7, 0x76, 0xed, 0xed, 0xde, 0xce, 0xa5, 0x26, 0x76, 0x8c, 0xae, 0xd9, 0x71, 0xed, 0xee, 0x22, - 0x4d, 0x43, 0x79, 0x46, 0xb1, 0x28, 0x28, 0x94, 0x55, 0x98, 0x5e, 0x36, 0x5b, 0x78, 0xc9, 0x23, - 0xac, 0x63, 0x17, 0x3d, 0x0d, 0x89, 0x1d, 0xb3, 0x85, 0x0b, 0xd2, 0x42, 0xfc, 0x42, 0xe6, 0xca, - 0x03, 0x8b, 0x7d, 0x4c, 0x8b, 0x61, 0x8e, 0x0d, 0x92, 0xac, 0x52, 0x0e, 0xe5, 0xff, 0x24, 0x60, - 0x26, 0x22, 0x17, 0x21, 0x48, 0x58, 0x7a, 0x9b, 0x20, 0x4a, 0x17, 0xd2, 0x2a, 0xfd, 0x1b, 0x15, - 0x60, 0xb2, 0xa3, 0x1b, 0xb7, 0xf4, 0x5d, 0x5c, 0x88, 0xd1, 0x64, 0xf1, 0x89, 0xce, 0x00, 0x34, - 0x71, 0x07, 0x5b, 0x4d, 0x6c, 0x19, 0x07, 0x85, 0xf8, 0x42, 0xfc, 0x42, 0x5a, 0x0d, 0xa4, 0xa0, - 0x47, 0x60, 0xba, 0xd3, 0xdb, 0x6e, 0x99, 0x86, 0x16, 0x20, 0x83, 0x85, 0xf8, 0x85, 0x09, 0x55, - 0x66, 0x19, 0x4b, 0x3e, 0xf1, 0x79, 0xc8, 0xdf, 0xc1, 0xfa, 0xad, 0x20, 0x69, 0x86, 0x92, 0x4e, - 0x91, 0xe4, 0x00, 0x61, 0x05, 0xb2, 0x6d, 0xec, 0x38, 0xfa, 0x2e, 0xd6, 0xdc, 0x83, 0x0e, 0x2e, - 0x24, 0x68, 0xeb, 0x17, 0x06, 0x5a, 0xdf, 0xdf, 0xf2, 0x0c, 0xe7, 0x6a, 0x1c, 0x74, 0x30, 0x2a, - 0x41, 0x1a, 0x5b, 0xbd, 0x36, 0x43, 0x98, 0x18, 0x22, 0xbf, 0xaa, 0xd5, 0x6b, 0xf7, 0xa3, 0xa4, - 0x08, 0x1b, 0x87, 0x98, 0x74, 0x70, 0xf7, 0xb6, 0x69, 0xe0, 0x42, 0x92, 0x02, 0x9c, 0x1f, 0x00, - 0xa8, 0xb3, 0xfc, 0x7e, 0x0c, 0xc1, 0x87, 0x2a, 0x90, 0xc6, 0xfb, 0x2e, 0xb6, 0x1c, 0xd3, 0xb6, - 0x0a, 0x93, 0x14, 0xe4, 0xc1, 0x88, 0x5e, 0xc4, 0xad, 0x66, 0x3f, 0x84, 0xcf, 0x87, 0xae, 0xc1, - 0xa4, 0xdd, 0x71, 0x4d, 0xdb, 0x72, 0x0a, 0xa9, 0x05, 0xe9, 0x42, 0xe6, 0xca, 0x7d, 0x91, 0x8a, - 0xb0, 0xce, 0x68, 0x54, 0x41, 0x8c, 0x6a, 0x20, 0x3b, 0x76, 0xaf, 0x6b, 0x60, 0xcd, 0xb0, 0x9b, - 0x58, 0x33, 0xad, 0x1d, 0xbb, 0x90, 0xa6, 0x00, 0xf3, 0x83, 0x0d, 0xa1, 0x84, 0x15, 0xbb, 0x89, - 0x6b, 0xd6, 0x8e, 0xad, 0x4e, 0x39, 0xa1, 0x6f, 0x74, 0x02, 0x92, 0xce, 0x81, 0xe5, 0xea, 0xfb, - 0x85, 0x2c, 0xd5, 0x10, 0xfe, 0x45, 0x54, 0x07, 0x37, 0x4d, 0x52, 0x5c, 0x21, 0xc7, 0x54, 0x87, - 0x7f, 0x2a, 0xbf, 0x94, 0x84, 0xfc, 0x38, 0xca, 0xf7, 0x2c, 0x4c, 0xec, 0x90, 0xf6, 0x17, 0x62, - 0x47, 0x91, 0x0e, 0xe3, 0x09, 0x8b, 0x37, 0x79, 0x8f, 0xe2, 0x2d, 0x41, 0xc6, 0xc2, 0x8e, 0x8b, - 0x9b, 0x4c, 0x57, 0xe2, 0x63, 0x6a, 0x1b, 0x30, 0xa6, 0x41, 0x65, 0x4b, 0xdc, 0x93, 0xb2, 0xbd, - 0x0c, 0x79, 0xaf, 0x4a, 0x5a, 0x57, 0xb7, 0x76, 0x85, 0xd6, 0x5e, 0x1a, 0x55, 0x93, 0xc5, 0xaa, - 0xe0, 0x53, 0x09, 0x9b, 0x3a, 0x85, 0x43, 0xdf, 0x68, 0x09, 0xc0, 0xb6, 0xb0, 0xbd, 0xa3, 0x35, - 0xb1, 0xd1, 0x2a, 0xa4, 0x86, 0x48, 0x69, 0x9d, 0x90, 0x0c, 0x48, 0xc9, 0x66, 0xa9, 0x46, 0x0b, - 0x3d, 0xe3, 0x2b, 0xe1, 0xe4, 0x10, 0x1d, 0x5a, 0x65, 0xc3, 0x6f, 0x40, 0x0f, 0x37, 0x61, 0xaa, - 0x8b, 0xc9, 0x88, 0xc0, 0x4d, 0xde, 0xb2, 0x34, 0xad, 0xc4, 0xe2, 0xc8, 0x96, 0xa9, 0x9c, 0x8d, - 0x35, 0x2c, 0xd7, 0x0d, 0x7e, 0xa2, 0x73, 0xe0, 0x25, 0x68, 0x54, 0xad, 0x80, 0xda, 0xa7, 0xac, - 0x48, 0x5c, 0xd3, 0xdb, 0x78, 0xee, 0x75, 0x98, 0x0a, 0x8b, 0x07, 0xcd, 0xc2, 0x84, 0xe3, 0xea, - 0x5d, 0x97, 0x6a, 0xe1, 0x84, 0xca, 0x3e, 0x90, 0x0c, 0x71, 0x6c, 0x35, 0xa9, 0xfd, 0x9b, 0x50, - 0xc9, 0x9f, 0xe8, 0xeb, 0xfc, 0x06, 0xc7, 0x69, 0x83, 0x1f, 0x1a, 0xec, 0xd1, 0x10, 0x72, 0x7f, - 0xbb, 0xe7, 0x9e, 0x82, 0x5c, 0xa8, 0x01, 0xe3, 0x16, 0xad, 0xfc, 0x74, 0x02, 0x8e, 0x47, 0x62, - 0xa3, 0x97, 0x61, 0xb6, 0x67, 0x99, 0x96, 0x8b, 0xbb, 0x9d, 0x2e, 0x26, 0x2a, 0xcb, 0xca, 0x2a, - 0xfc, 0xe1, 0xe4, 0x10, 0xa5, 0xdb, 0x0c, 0x52, 0x33, 0x14, 0x75, 0xa6, 0x37, 0x98, 0x88, 0x5e, - 0x81, 0x0c, 0xd1, 0x0f, 0xbd, 0xab, 0x53, 0x40, 0x36, 0x1a, 0xaf, 0x8c, 0xd7, 0xe4, 0xc5, 0x25, - 0x9f, 0xb3, 0x1c, 0x7f, 0xbf, 0x14, 0x53, 0x83, 0x58, 0x68, 0x0f, 0xb2, 0xb7, 0x71, 0xd7, 0xdc, - 0x31, 0x0d, 0x86, 0x4d, 0xc4, 0x39, 0x75, 0xe5, 0xe9, 0x31, 0xb1, 0xb7, 0x02, 0xac, 0x75, 0x57, - 0x77, 0x71, 0x11, 0x36, 0xd7, 0xb6, 0xaa, 0x6a, 0x6d, 0xb9, 0x56, 0x5d, 0x52, 0x43, 0xc8, 0x73, - 0x9f, 0x92, 0x20, 0x13, 0xa8, 0x0b, 0x31, 0x5b, 0x56, 0xaf, 0xbd, 0x8d, 0xbb, 0x5c, 0xe2, 0xfc, - 0x0b, 0x9d, 0x86, 0xf4, 0x4e, 0xaf, 0xd5, 0x62, 0x6a, 0xc3, 0xe6, 0xbc, 0x14, 0x49, 0x20, 0x2a, - 0x43, 0xac, 0x14, 0x37, 0x04, 0xd4, 0x4a, 0x91, 0xbf, 0xd1, 0x39, 0xc8, 0x98, 0x8e, 0xd6, 0xc5, - 0x1d, 0xac, 0xbb, 0xb8, 0x59, 0x48, 0x2c, 0x48, 0x17, 0x52, 0xe5, 0x58, 0x41, 0x52, 0xc1, 0x74, - 0x54, 0x9e, 0x8a, 0xe6, 0x20, 0x25, 0x74, 0xaf, 0x30, 0x41, 0x28, 0x54, 0xef, 0x9b, 0xe5, 0x71, - 0xee, 0xa4, 0xc8, 0x63, 0xdf, 0xca, 0x55, 0x98, 0x1e, 0x68, 0x24, 0xca, 0x43, 0x66, 0xa9, 0x5a, - 0x59, 0x29, 0xa9, 0xa5, 0x46, 0x6d, 0x7d, 0x4d, 0x3e, 0x86, 0xa6, 0x20, 0xd0, 0x6e, 0x59, 0xba, - 0x98, 0x4e, 0x7d, 0x7e, 0x52, 0x7e, 0xef, 0x7b, 0xdf, 0xfb, 0xde, 0x98, 0xf2, 0x2b, 0x49, 0x98, - 0x8d, 0xb2, 0x72, 0x91, 0x06, 0xd7, 0x97, 0x49, 0x3c, 0x24, 0x93, 0x12, 0x4c, 0xb4, 0xf4, 0x6d, - 0xdc, 0xa2, 0x8d, 0x9b, 0xba, 0xf2, 0xc8, 0x58, 0x76, 0x74, 0x71, 0x85, 0xb0, 0xa8, 0x8c, 0x13, - 0xbd, 0xc0, 0x25, 0x37, 0x41, 0x11, 0x2e, 0x8e, 0x87, 0x40, 0xac, 0x1f, 0x97, 0xf2, 0x69, 0x48, - 0x93, 0xff, 0x59, 0xb7, 0x24, 0x59, 0xb7, 0x90, 0x04, 0xda, 0x2d, 0x73, 0x90, 0xa2, 0x86, 0xad, - 0x89, 0xbd, 0x2e, 0x13, 0xdf, 0xc4, 0x14, 0x34, 0xf1, 0x8e, 0xde, 0x6b, 0xb9, 0xda, 0x6d, 0xbd, - 0xd5, 0xc3, 0xd4, 0x44, 0xa5, 0xd5, 0x2c, 0x4f, 0xdc, 0x22, 0x69, 0x68, 0x1e, 0x32, 0xcc, 0x0e, - 0x9a, 0x56, 0x13, 0xef, 0xd3, 0x99, 0x70, 0x42, 0x65, 0xa6, 0xb1, 0x46, 0x52, 0x48, 0xf1, 0xaf, - 0x39, 0xb6, 0x25, 0x8c, 0x09, 0x2d, 0x82, 0x24, 0xd0, 0xe2, 0x9f, 0xea, 0x9f, 0x84, 0xef, 0x8f, - 0x6e, 0xde, 0x80, 0xf5, 0x3b, 0x0f, 0x79, 0x4a, 0xf1, 0x04, 0x1f, 0xab, 0x7a, 0xab, 0x30, 0x4d, - 0x15, 0x60, 0x8a, 0x25, 0xaf, 0xf3, 0x54, 0xe5, 0x17, 0x62, 0x90, 0xa0, 0x53, 0x41, 0x1e, 0x32, - 0x8d, 0x57, 0x36, 0xaa, 0xda, 0xd2, 0xfa, 0x66, 0x79, 0xa5, 0x2a, 0x4b, 0xa4, 0xeb, 0x69, 0xc2, - 0xf2, 0xca, 0x7a, 0xa9, 0x21, 0xc7, 0xbc, 0xef, 0xda, 0x5a, 0xe3, 0xda, 0x55, 0x39, 0xee, 0x31, - 0x6c, 0xb2, 0x84, 0x44, 0x90, 0xe0, 0x89, 0x2b, 0xf2, 0x04, 0x92, 0x21, 0xcb, 0x00, 0x6a, 0x2f, - 0x57, 0x97, 0xae, 0x5d, 0x95, 0x93, 0xe1, 0x94, 0x27, 0xae, 0xc8, 0x93, 0x28, 0x07, 0x69, 0x9a, - 0x52, 0x5e, 0x5f, 0x5f, 0x91, 0x53, 0x1e, 0x66, 0xbd, 0xa1, 0xd6, 0xd6, 0xae, 0xcb, 0x69, 0x0f, - 0xf3, 0xba, 0xba, 0xbe, 0xb9, 0x21, 0x83, 0x87, 0xb0, 0x5a, 0xad, 0xd7, 0x4b, 0xd7, 0xab, 0x72, - 0xc6, 0xa3, 0x28, 0xbf, 0xd2, 0xa8, 0xd6, 0xe5, 0x6c, 0xa8, 0x5a, 0x4f, 0x5c, 0x91, 0x73, 0x5e, - 0x11, 0xd5, 0xb5, 0xcd, 0x55, 0x79, 0x0a, 0x4d, 0x43, 0x8e, 0x15, 0x21, 0x2a, 0x91, 0xef, 0x4b, - 0xba, 0x76, 0x55, 0x96, 0xfd, 0x8a, 0x30, 0x94, 0xe9, 0x50, 0xc2, 0xb5, 0xab, 0x32, 0x52, 0x2a, - 0x30, 0x41, 0xd5, 0x10, 0x21, 0x98, 0x5a, 0x29, 0x95, 0xab, 0x2b, 0xda, 0xfa, 0x06, 0x19, 0x34, - 0xa5, 0x15, 0x59, 0xf2, 0xd3, 0xd4, 0xea, 0xbb, 0x36, 0x6b, 0x6a, 0x75, 0x49, 0x8e, 0x05, 0xd3, - 0x36, 0xaa, 0xa5, 0x46, 0x75, 0x49, 0x8e, 0x2b, 0x06, 0xcc, 0x46, 0x4d, 0x81, 0x91, 0x43, 0x28, - 0xa0, 0x0b, 0xb1, 0x21, 0xba, 0x40, 0xb1, 0xfa, 0x75, 0x41, 0xf9, 0x5c, 0x0c, 0x66, 0x22, 0xdc, - 0x80, 0xc8, 0x42, 0x5e, 0x84, 0x09, 0xa6, 0xcb, 0xcc, 0x14, 0x3f, 0x1c, 0xe9, 0x4f, 0x50, 0xcd, - 0x1e, 0x70, 0x8e, 0x28, 0x5f, 0xd0, 0x6d, 0x8c, 0x0f, 0x71, 0x1b, 0x09, 0xc4, 0x80, 0xc2, 0x7e, - 0xe3, 0xc0, 0x74, 0xcd, 0x3c, 0x9a, 0x6b, 0xe3, 0x78, 0x34, 0x34, 0xed, 0x68, 0xd3, 0xf6, 0x44, - 0xc4, 0xb4, 0xfd, 0x2c, 0x4c, 0x0f, 0x00, 0x8d, 0x3d, 0x7d, 0x7e, 0xab, 0x04, 0x85, 0x61, 0xc2, - 0x19, 0x61, 0x12, 0x63, 0x21, 0x93, 0xf8, 0x6c, 0xbf, 0x04, 0xcf, 0x0e, 0xef, 0x84, 0x81, 0xbe, - 0xfe, 0xb8, 0x04, 0x27, 0xa2, 0x97, 0x07, 0x91, 0x75, 0x78, 0x01, 0x92, 0x6d, 0xec, 0xee, 0xd9, - 0xc2, 0x11, 0x7e, 0x28, 0xc2, 0xbd, 0x22, 0xd9, 0xfd, 0x9d, 0xcd, 0xb9, 0x82, 0xfe, 0x59, 0x7c, - 0x98, 0x8f, 0xcf, 0x6a, 0x33, 0x50, 0xd3, 0xef, 0x88, 0xc1, 0xf1, 0x48, 0xf0, 0xc8, 0x8a, 0xde, - 0x0f, 0x60, 0x5a, 0x9d, 0x9e, 0xcb, 0x9c, 0x5d, 0x66, 0x89, 0xd3, 0x34, 0x85, 0x1a, 0x2f, 0x62, - 0x65, 0x7b, 0xae, 0x97, 0xcf, 0x26, 0x51, 0x60, 0x49, 0x94, 0xe0, 0x69, 0xbf, 0xa2, 0x09, 0x5a, - 0xd1, 0x33, 0x43, 0x5a, 0x3a, 0xa0, 0x98, 0x8f, 0x83, 0x6c, 0xb4, 0x4c, 0x6c, 0xb9, 0x9a, 0xe3, - 0x76, 0xb1, 0xde, 0x36, 0xad, 0x5d, 0x36, 0xcf, 0x16, 0x27, 0x76, 0xf4, 0x96, 0x83, 0xd5, 0x3c, - 0xcb, 0xae, 0x8b, 0x5c, 0xc2, 0x41, 0x15, 0xa8, 0x1b, 0xe0, 0x48, 0x86, 0x38, 0x58, 0xb6, 0xc7, - 0xa1, 0x7c, 0x6f, 0x1a, 0x32, 0x81, 0xc5, 0x14, 0x3a, 0x0b, 0xd9, 0xd7, 0xf4, 0xdb, 0xba, 0x26, - 0x16, 0xc8, 0x4c, 0x12, 0x19, 0x92, 0xb6, 0xc1, 0x17, 0xc9, 0x8f, 0xc3, 0x2c, 0x25, 0xb1, 0x7b, - 0x2e, 0xee, 0x6a, 0x46, 0x4b, 0x77, 0x1c, 0x2a, 0xb4, 0x14, 0x25, 0x45, 0x24, 0x6f, 0x9d, 0x64, - 0x55, 0x44, 0x0e, 0x7a, 0x12, 0x66, 0x28, 0x47, 0xbb, 0xd7, 0x72, 0xcd, 0x4e, 0x0b, 0x6b, 0x64, - 0xc9, 0xee, 0xd0, 0x29, 0xc7, 0xab, 0xd9, 0x34, 0xa1, 0x58, 0xe5, 0x04, 0xa4, 0x46, 0x0e, 0x5a, - 0x82, 0xfb, 0x29, 0xdb, 0x2e, 0xb6, 0x70, 0x57, 0x77, 0xb1, 0x86, 0xdf, 0xd3, 0xd3, 0x5b, 0x8e, - 0xa6, 0x5b, 0x4d, 0x6d, 0x4f, 0x77, 0xf6, 0x0a, 0xb3, 0x9e, 0x5b, 0x72, 0x8a, 0x10, 0x5e, 0xe7, - 0x74, 0x55, 0x4a, 0x56, 0xb2, 0x9a, 0x37, 0x74, 0x67, 0x0f, 0x15, 0xe1, 0x04, 0x45, 0x71, 0xdc, - 0xae, 0x69, 0xed, 0x6a, 0xc6, 0x1e, 0x36, 0x6e, 0x69, 0x3d, 0x77, 0xe7, 0xe9, 0xc2, 0xe9, 0x60, - 0xf9, 0xb4, 0x86, 0x75, 0x4a, 0x53, 0x21, 0x24, 0x9b, 0xee, 0xce, 0xd3, 0xa8, 0x0e, 0x59, 0xd2, - 0x19, 0x6d, 0xf3, 0x75, 0xac, 0xed, 0xd8, 0x5d, 0x3a, 0x87, 0x4e, 0x45, 0x98, 0xa6, 0x80, 0x04, - 0x17, 0xd7, 0x39, 0xc3, 0xaa, 0xdd, 0xc4, 0xc5, 0x89, 0xfa, 0x46, 0xb5, 0xba, 0xa4, 0x66, 0x04, - 0xca, 0xb2, 0xdd, 0x25, 0x0a, 0xb5, 0x6b, 0x7b, 0x02, 0xce, 0x30, 0x85, 0xda, 0xb5, 0x85, 0x78, - 0x9f, 0x84, 0x19, 0xc3, 0x60, 0x6d, 0x36, 0x0d, 0x8d, 0x2f, 0xac, 0x9d, 0x82, 0x1c, 0x12, 0x96, - 0x61, 0x5c, 0x67, 0x04, 0x5c, 0xc7, 0x1d, 0xf4, 0x0c, 0x1c, 0xf7, 0x85, 0x15, 0x64, 0x9c, 0x1e, - 0x68, 0x65, 0x3f, 0xeb, 0x93, 0x30, 0xd3, 0x39, 0x18, 0x64, 0x44, 0xa1, 0x12, 0x3b, 0x07, 0xfd, - 0x6c, 0x4f, 0xc1, 0x6c, 0x67, 0xaf, 0x33, 0xc8, 0x77, 0x31, 0xc8, 0x87, 0x3a, 0x7b, 0x9d, 0x7e, - 0xc6, 0x07, 0x69, 0x94, 0xa5, 0x8b, 0x0d, 0xea, 0x1d, 0x9e, 0x0c, 0x92, 0x07, 0x32, 0xd0, 0x22, - 0xc8, 0x86, 0xa1, 0x61, 0x4b, 0xdf, 0x6e, 0x61, 0x4d, 0xef, 0x62, 0x4b, 0x77, 0x0a, 0xf3, 0x94, - 0x38, 0xe1, 0x76, 0x7b, 0x58, 0x9d, 0x32, 0x8c, 0x2a, 0xcd, 0x2c, 0xd1, 0x3c, 0x74, 0x11, 0xa6, - 0xed, 0xed, 0xd7, 0x0c, 0xa6, 0x91, 0x5a, 0xa7, 0x8b, 0x77, 0xcc, 0xfd, 0xc2, 0x03, 0x54, 0xbc, - 0x79, 0x92, 0x41, 0xf5, 0x71, 0x83, 0x26, 0xa3, 0x87, 0x41, 0x36, 0x9c, 0x3d, 0xbd, 0xdb, 0xa1, - 0x26, 0xd9, 0xe9, 0xe8, 0x06, 0x2e, 0x3c, 0xc8, 0x48, 0x59, 0xfa, 0x9a, 0x48, 0x26, 0x23, 0xc2, - 0xb9, 0x63, 0xee, 0xb8, 0x02, 0xf1, 0x3c, 0x1b, 0x11, 0x34, 0x8d, 0xa3, 0x5d, 0x00, 0x99, 0x48, - 0x22, 0x54, 0xf0, 0x05, 0x4a, 0x36, 0xd5, 0xd9, 0xeb, 0x04, 0xcb, 0x3d, 0x07, 0x39, 0x42, 0xe9, - 0x17, 0xfa, 0x30, 0x73, 0xdc, 0x3a, 0x7b, 0x81, 0x12, 0xaf, 0xc2, 0x09, 0x42, 0xd4, 0xc6, 0xae, - 0xde, 0xd4, 0x5d, 0x3d, 0x40, 0xfd, 0x28, 0xa5, 0x26, 0x62, 0x5f, 0xe5, 0x99, 0xa1, 0x7a, 0x76, - 0x7b, 0xdb, 0x07, 0x9e, 0x62, 0x3d, 0xc6, 0xea, 0x49, 0xd2, 0x84, 0x6a, 0xbd, 0x63, 0xab, 0x29, - 0xa5, 0x08, 0xd9, 0xa0, 0xde, 0xa3, 0x34, 0x30, 0xcd, 0x97, 0x25, 0xe2, 0x04, 0x55, 0xd6, 0x97, - 0x88, 0xfb, 0xf2, 0x6a, 0x55, 0x8e, 0x11, 0x37, 0x6a, 0xa5, 0xd6, 0xa8, 0x6a, 0xea, 0xe6, 0x5a, - 0xa3, 0xb6, 0x5a, 0x95, 0xe3, 0x01, 0xc7, 0xfe, 0x66, 0x22, 0xf5, 0x90, 0x7c, 0x5e, 0xf9, 0xe5, - 0x38, 0x4c, 0x85, 0xd7, 0xd6, 0xe8, 0x39, 0x38, 0x29, 0x42, 0x64, 0x0e, 0x76, 0xb5, 0x3b, 0x66, - 0x97, 0x0e, 0xc8, 0xb6, 0xce, 0x26, 0x47, 0x4f, 0x7f, 0x66, 0x39, 0x55, 0x1d, 0xbb, 0xef, 0x36, - 0xbb, 0x64, 0xb8, 0xb5, 0x75, 0x17, 0xad, 0xc0, 0xbc, 0x65, 0x6b, 0x8e, 0xab, 0x5b, 0x4d, 0xbd, - 0xdb, 0xd4, 0xfc, 0xe0, 0xa4, 0xa6, 0x1b, 0x06, 0x76, 0x1c, 0x9b, 0x4d, 0x84, 0x1e, 0xca, 0x7d, - 0x96, 0x5d, 0xe7, 0xc4, 0xfe, 0x0c, 0x51, 0xe2, 0xa4, 0x7d, 0xea, 0x1b, 0x1f, 0xa6, 0xbe, 0xa7, - 0x21, 0xdd, 0xd6, 0x3b, 0x1a, 0xb6, 0xdc, 0xee, 0x01, 0xf5, 0xcf, 0x53, 0x6a, 0xaa, 0xad, 0x77, - 0xaa, 0xe4, 0x1b, 0x6d, 0xc1, 0x43, 0x3e, 0xa9, 0xd6, 0xc2, 0xbb, 0xba, 0x71, 0xa0, 0x51, 0x67, - 0x9c, 0x06, 0x7a, 0x34, 0xc3, 0xb6, 0x76, 0x5a, 0xa6, 0xe1, 0x3a, 0xd4, 0x3e, 0x30, 0x1b, 0xa7, - 0xf8, 0x1c, 0x2b, 0x94, 0xe1, 0xa6, 0x63, 0x5b, 0xd4, 0x07, 0xaf, 0x08, 0xea, 0x77, 0xae, 0x87, - 0xc3, 0xbd, 0x94, 0x90, 0x27, 0x6e, 0x26, 0x52, 0x13, 0x72, 0xf2, 0x66, 0x22, 0x95, 0x94, 0x27, - 0x6f, 0x26, 0x52, 0x29, 0x39, 0x7d, 0x33, 0x91, 0x4a, 0xcb, 0xa0, 0xbc, 0x2f, 0x0d, 0xd9, 0xe0, - 0xca, 0x80, 0x2c, 0xb4, 0x0c, 0x3a, 0x37, 0x4a, 0xd4, 0x7a, 0x9e, 0x3b, 0x74, 0x1d, 0xb1, 0x58, - 0x21, 0x93, 0x66, 0x31, 0xc9, 0xdc, 0x70, 0x95, 0x71, 0x12, 0x87, 0x85, 0xa8, 0x35, 0x66, 0x6e, - 0x4f, 0x4a, 0xe5, 0x5f, 0xe8, 0x3a, 0x24, 0x5f, 0x73, 0x28, 0x76, 0x92, 0x62, 0x3f, 0x70, 0x38, - 0xf6, 0xcd, 0x3a, 0x05, 0x4f, 0xdf, 0xac, 0x6b, 0x6b, 0xeb, 0xea, 0x6a, 0x69, 0x45, 0xe5, 0xec, - 0xe8, 0x14, 0x24, 0x5a, 0xfa, 0xeb, 0x07, 0xe1, 0xe9, 0x95, 0x26, 0xa1, 0x45, 0xc8, 0xf7, 0x2c, - 0xb6, 0xea, 0x26, 0x5d, 0x45, 0xa8, 0xf2, 0x41, 0xaa, 0x29, 0x3f, 0x77, 0x85, 0xd0, 0x8f, 0xa9, - 0x1e, 0xa7, 0x20, 0x71, 0x07, 0xeb, 0xb7, 0xc2, 0x93, 0x20, 0x4d, 0x42, 0x17, 0x20, 0xdb, 0xc4, - 0xdb, 0xbd, 0x5d, 0xad, 0x8b, 0x9b, 0xba, 0xe1, 0x86, 0x4d, 0x7f, 0x86, 0x66, 0xa9, 0x34, 0x07, - 0xbd, 0x04, 0x69, 0xd2, 0x47, 0x16, 0xed, 0xe3, 0x69, 0x2a, 0x82, 0xc7, 0x0e, 0x17, 0x01, 0xef, - 0x62, 0xc1, 0xa4, 0xfa, 0xfc, 0xe8, 0x26, 0x24, 0x5d, 0xbd, 0xbb, 0x8b, 0x5d, 0x6a, 0xf9, 0xa7, - 0x22, 0xc2, 0x55, 0x11, 0x48, 0x0d, 0xca, 0x41, 0xc4, 0x4a, 0x75, 0x94, 0x23, 0xa0, 0x1b, 0x30, - 0xc9, 0xfe, 0x72, 0x0a, 0x33, 0x0b, 0xf1, 0xa3, 0x83, 0xa9, 0x82, 0xfd, 0x1d, 0xb4, 0x59, 0x97, - 0x60, 0x82, 0x2a, 0x1b, 0x02, 0xe0, 0xea, 0x26, 0x1f, 0x43, 0x29, 0x48, 0x54, 0xd6, 0x55, 0x62, - 0xb7, 0x64, 0xc8, 0xb2, 0x54, 0x6d, 0xa3, 0x56, 0xad, 0x54, 0xe5, 0x98, 0xf2, 0x24, 0x24, 0x99, - 0x06, 0x11, 0x9b, 0xe6, 0xe9, 0x90, 0x7c, 0x8c, 0x7f, 0x72, 0x0c, 0x49, 0xe4, 0x6e, 0xae, 0x96, - 0xab, 0xaa, 0x1c, 0x53, 0x36, 0x21, 0xdf, 0x27, 0x75, 0x74, 0x1c, 0xa6, 0xd5, 0x6a, 0xa3, 0xba, - 0x46, 0x56, 0x6d, 0xda, 0xe6, 0xda, 0x4b, 0x6b, 0xeb, 0xef, 0x5e, 0x93, 0x8f, 0x85, 0x93, 0x85, - 0x81, 0x94, 0xd0, 0x2c, 0xc8, 0x7e, 0x72, 0x7d, 0x7d, 0x53, 0xa5, 0xb5, 0xf9, 0xae, 0x18, 0xc8, - 0xfd, 0x62, 0x43, 0x27, 0x61, 0xa6, 0x51, 0x52, 0xaf, 0x57, 0x1b, 0x1a, 0x5b, 0x89, 0x7a, 0xd0, - 0xb3, 0x20, 0x07, 0x33, 0x96, 0x6b, 0x74, 0xa1, 0x3d, 0x0f, 0xa7, 0x83, 0xa9, 0xd5, 0x97, 0x1b, - 0xd5, 0xb5, 0x3a, 0x2d, 0xbc, 0xb4, 0x76, 0x9d, 0x58, 0xeb, 0x3e, 0x3c, 0xb1, 0xf6, 0x8d, 0x93, - 0xaa, 0x86, 0xf1, 0xaa, 0x2b, 0x4b, 0x72, 0xa2, 0x3f, 0x79, 0x7d, 0xad, 0xba, 0xbe, 0x2c, 0x4f, - 0xf4, 0x97, 0x4e, 0xd7, 0xc3, 0x49, 0x34, 0x07, 0x27, 0xfa, 0x53, 0xb5, 0xea, 0x5a, 0x43, 0x7d, - 0x45, 0x9e, 0xec, 0x2f, 0xb8, 0x5e, 0x55, 0xb7, 0x6a, 0x95, 0xaa, 0x9c, 0x42, 0x27, 0x00, 0x85, - 0x6b, 0xd4, 0xb8, 0xb1, 0xbe, 0x24, 0xa7, 0x07, 0xec, 0x93, 0xe2, 0x40, 0x36, 0xb8, 0x28, 0xfd, - 0xaa, 0x98, 0x46, 0xe5, 0x83, 0x31, 0xc8, 0x04, 0x16, 0x99, 0x64, 0x75, 0xa0, 0xb7, 0x5a, 0xf6, - 0x1d, 0x4d, 0x6f, 0x99, 0xba, 0xc3, 0xad, 0x17, 0xd0, 0xa4, 0x12, 0x49, 0x19, 0xd7, 0x5a, 0x8c, - 0x3f, 0x5f, 0x24, 0xbf, 0x16, 0xe7, 0x8b, 0x09, 0x39, 0xa9, 0x7c, 0x54, 0x02, 0xb9, 0x7f, 0xf5, - 0xd8, 0xd7, 0x7c, 0x69, 0x58, 0xf3, 0xbf, 0x2a, 0x7d, 0xf7, 0x11, 0x09, 0xa6, 0xc2, 0x4b, 0xc6, - 0xbe, 0xea, 0x9d, 0xfd, 0x2b, 0xad, 0xde, 0xef, 0xc5, 0x20, 0x17, 0x5a, 0x28, 0x8e, 0x5b, 0xbb, - 0xf7, 0xc0, 0xb4, 0xd9, 0xc4, 0xed, 0x8e, 0xed, 0x62, 0xcb, 0x38, 0xd0, 0x5a, 0xf8, 0x36, 0x6e, - 0x15, 0x14, 0x6a, 0xe2, 0x2f, 0x1d, 0xbe, 0x14, 0x5d, 0xac, 0xf9, 0x7c, 0x2b, 0x84, 0xad, 0x38, - 0x53, 0x5b, 0xaa, 0xae, 0x6e, 0xac, 0x37, 0xaa, 0x6b, 0x95, 0x57, 0x84, 0x75, 0x51, 0x65, 0xb3, - 0x8f, 0xec, 0x1d, 0x34, 0xda, 0x1b, 0x20, 0xf7, 0x57, 0x8a, 0xd8, 0x8a, 0x88, 0x6a, 0xc9, 0xc7, - 0xd0, 0x0c, 0xe4, 0xd7, 0xd6, 0xb5, 0x7a, 0x6d, 0xa9, 0xaa, 0x55, 0x97, 0x97, 0xab, 0x95, 0x46, - 0x9d, 0x05, 0x17, 0x3d, 0xea, 0x86, 0x1c, 0x0b, 0x8a, 0xf8, 0x43, 0x71, 0x98, 0x89, 0xa8, 0x09, - 0x2a, 0xf1, 0xb0, 0x00, 0x8b, 0x54, 0x3c, 0x36, 0x4e, 0xed, 0x17, 0x89, 0x63, 0xbe, 0xa1, 0x77, - 0x5d, 0x1e, 0x45, 0x78, 0x18, 0x88, 0x94, 0x2c, 0x97, 0xf8, 0x09, 0x5d, 0x1e, 0xb4, 0x65, 0xb1, - 0x82, 0xbc, 0x9f, 0xce, 0xe2, 0xb6, 0x8f, 0x02, 0xea, 0xd8, 0x8e, 0xe9, 0x9a, 0xb7, 0xb1, 0x66, - 0x5a, 0x22, 0xc2, 0x9b, 0x58, 0x90, 0x2e, 0x24, 0x54, 0x59, 0xe4, 0xd4, 0x2c, 0xd7, 0xa3, 0xb6, - 0xf0, 0xae, 0xde, 0x47, 0x4d, 0xfc, 0x98, 0xb8, 0x2a, 0x8b, 0x1c, 0x8f, 0xfa, 0x2c, 0x64, 0x9b, - 0x76, 0x8f, 0x2c, 0xa8, 0x18, 0x1d, 0xb1, 0x16, 0x92, 0x9a, 0x61, 0x69, 0x1e, 0x09, 0x5f, 0x2a, - 0xfb, 0xa1, 0xe5, 0xac, 0x9a, 0x61, 0x69, 0x8c, 0xe4, 0x3c, 0xe4, 0xf5, 0xdd, 0xdd, 0x2e, 0x01, - 0x17, 0x40, 0x6c, 0xf1, 0x3f, 0xe5, 0x25, 0x53, 0xc2, 0xb9, 0x9b, 0x90, 0x12, 0x72, 0x20, 0xfe, - 0x30, 0x91, 0x84, 0xd6, 0x61, 0x11, 0xad, 0xd8, 0x85, 0xb4, 0x9a, 0xb2, 0x44, 0xe6, 0x59, 0xc8, - 0x9a, 0x8e, 0xe6, 0xef, 0x6d, 0xc6, 0x16, 0x62, 0x17, 0x52, 0x6a, 0xc6, 0x74, 0xbc, 0x3d, 0x12, - 0xe5, 0xe3, 0x31, 0x98, 0x0a, 0xef, 0xda, 0xa2, 0x25, 0x48, 0xb5, 0x6c, 0xbe, 0xc9, 0xc2, 0x8e, - 0x0c, 0x5c, 0x18, 0xb1, 0xd1, 0xbb, 0xb8, 0xc2, 0xe9, 0x55, 0x8f, 0x73, 0xee, 0x37, 0x25, 0x48, - 0x89, 0x64, 0x74, 0x02, 0x12, 0x1d, 0xdd, 0xdd, 0xa3, 0x70, 0x13, 0xe5, 0x98, 0x2c, 0xa9, 0xf4, - 0x9b, 0xa4, 0x3b, 0x1d, 0x9d, 0xed, 0x13, 0xf1, 0x74, 0xf2, 0x4d, 0xfa, 0xb5, 0x85, 0xf5, 0x26, - 0x8d, 0x2c, 0xd8, 0xed, 0x36, 0xb6, 0x5c, 0x47, 0xf4, 0x2b, 0x4f, 0xaf, 0xf0, 0x64, 0xf4, 0x08, - 0x4c, 0xbb, 0x5d, 0xdd, 0x6c, 0x85, 0x68, 0x13, 0x94, 0x56, 0x16, 0x19, 0x1e, 0x71, 0x11, 0x4e, - 0x09, 0xdc, 0x26, 0x76, 0x75, 0x63, 0x0f, 0x37, 0x7d, 0xa6, 0x24, 0x8d, 0x20, 0x9e, 0xe4, 0x04, - 0x4b, 0x3c, 0x5f, 0xf0, 0x2a, 0x9f, 0x89, 0xc1, 0xb4, 0x88, 0x85, 0x34, 0x3d, 0x61, 0xad, 0x02, - 0xe8, 0x96, 0x65, 0xbb, 0x41, 0x71, 0x0d, 0xaa, 0xf2, 0x00, 0xdf, 0x62, 0xc9, 0x63, 0x52, 0x03, - 0x00, 0x73, 0x5f, 0x90, 0x00, 0xfc, 0xac, 0xa1, 0x72, 0x9b, 0x87, 0x0c, 0xdf, 0x93, 0xa7, 0x07, - 0x3b, 0x58, 0xf8, 0x0c, 0x58, 0xd2, 0xb2, 0xd9, 0xa2, 0x41, 0xce, 0x6d, 0xbc, 0x6b, 0x5a, 0x7c, - 0x77, 0x86, 0x7d, 0x88, 0x20, 0x67, 0xc2, 0xdf, 0x9e, 0x54, 0x21, 0xe5, 0xe0, 0xb6, 0x6e, 0xb9, - 0xa6, 0xc1, 0xf7, 0x5b, 0xae, 0x1d, 0xa9, 0xf2, 0x8b, 0x75, 0xce, 0xad, 0x7a, 0x38, 0xca, 0x05, - 0x48, 0x89, 0x54, 0xe2, 0xf8, 0xad, 0xad, 0xaf, 0x55, 0xe5, 0x63, 0x68, 0x12, 0xe2, 0xf5, 0x6a, - 0x43, 0x96, 0xc8, 0x22, 0xb6, 0xb4, 0x52, 0x2b, 0xd5, 0xe5, 0x58, 0xf9, 0x6f, 0xc3, 0x8c, 0x61, - 0xb7, 0xfb, 0x0b, 0x2c, 0xcb, 0x7d, 0x01, 0x44, 0xe7, 0x86, 0xf4, 0xea, 0x63, 0x9c, 0x68, 0xd7, - 0x6e, 0xe9, 0xd6, 0xee, 0xa2, 0xdd, 0xdd, 0xf5, 0x8f, 0xc5, 0x90, 0xb5, 0x86, 0x13, 0x38, 0x1c, - 0xd3, 0xd9, 0xfe, 0x4b, 0x49, 0xfa, 0xd1, 0x58, 0xfc, 0xfa, 0x46, 0xf9, 0x27, 0x63, 0x73, 0xd7, - 0x19, 0xe3, 0x86, 0x68, 0x8e, 0x8a, 0x77, 0x5a, 0xd8, 0x20, 0x95, 0x87, 0x3f, 0x7e, 0x04, 0x66, - 0x77, 0xed, 0x5d, 0x9b, 0x22, 0x5d, 0x22, 0x7f, 0xf1, 0x73, 0x35, 0x69, 0x2f, 0x75, 0x6e, 0xe4, - 0x21, 0x9c, 0xe2, 0x1a, 0xcc, 0x70, 0x62, 0x8d, 0x6e, 0xdf, 0xb3, 0x50, 0x05, 0x3a, 0x34, 0x4e, - 0x5e, 0xf8, 0xb9, 0x3f, 0xa0, 0x5e, 0x89, 0x3a, 0xcd, 0x59, 0x49, 0x1e, 0x8b, 0x66, 0x14, 0x55, - 0x38, 0x1e, 0xc2, 0x63, 0x36, 0x02, 0x77, 0x47, 0x20, 0xfe, 0x5b, 0x8e, 0x38, 0x13, 0x40, 0xac, - 0x73, 0xd6, 0x62, 0x05, 0x72, 0x47, 0xc1, 0xfa, 0x55, 0x8e, 0x95, 0xc5, 0x41, 0x90, 0xeb, 0x90, - 0xa7, 0x20, 0x46, 0xcf, 0x71, 0xed, 0x36, 0x35, 0xc0, 0x87, 0xc3, 0xfc, 0xbb, 0x3f, 0x60, 0x83, - 0x76, 0x8a, 0xb0, 0x55, 0x3c, 0xae, 0x62, 0x11, 0xe8, 0x89, 0x85, 0x26, 0x36, 0x5a, 0x23, 0x10, - 0x7e, 0x8d, 0x57, 0xc4, 0xa3, 0x2f, 0x6e, 0xc1, 0x2c, 0xf9, 0x9b, 0xda, 0xc7, 0x60, 0x4d, 0x46, - 0x07, 0xd5, 0x0b, 0xff, 0xe9, 0x5b, 0x99, 0x5d, 0x98, 0xf1, 0x00, 0x02, 0x75, 0x0a, 0xf4, 0xe2, - 0x2e, 0x76, 0x5d, 0xdc, 0x75, 0x34, 0xbd, 0x15, 0x55, 0xbd, 0x40, 0x54, 0xb2, 0xf0, 0x43, 0x5f, - 0x0c, 0xf7, 0xe2, 0x75, 0xc6, 0x59, 0x6a, 0xb5, 0x8a, 0x9b, 0x70, 0x32, 0x42, 0x2b, 0xc6, 0xc0, - 0xfc, 0x10, 0xc7, 0x9c, 0x1d, 0xd0, 0x0c, 0x02, 0xbb, 0x01, 0x22, 0xdd, 0xeb, 0xcb, 0x31, 0x30, - 0x3f, 0xcc, 0x31, 0x11, 0xe7, 0x15, 0x5d, 0x4a, 0x10, 0x6f, 0xc2, 0xf4, 0x6d, 0xdc, 0xdd, 0xb6, - 0x1d, 0x1e, 0x09, 0x1e, 0x03, 0xee, 0x23, 0x1c, 0x2e, 0xcf, 0x19, 0x69, 0x68, 0x98, 0x60, 0x3d, - 0x03, 0xa9, 0x1d, 0xdd, 0xc0, 0x63, 0x40, 0xdc, 0xe5, 0x10, 0x93, 0x84, 0x9e, 0xb0, 0x96, 0x20, - 0xbb, 0x6b, 0xf3, 0x29, 0x72, 0x34, 0xfb, 0x47, 0x39, 0x7b, 0x46, 0xf0, 0x70, 0x88, 0x8e, 0xdd, - 0xe9, 0xb5, 0xc8, 0xfc, 0x39, 0x1a, 0xe2, 0x87, 0x05, 0x84, 0xe0, 0xe1, 0x10, 0x47, 0x10, 0xeb, - 0xc7, 0x04, 0x84, 0x13, 0x90, 0xe7, 0x8b, 0x90, 0xb1, 0xad, 0xd6, 0x81, 0x6d, 0x8d, 0x53, 0x89, - 0x1f, 0xe1, 0x08, 0xc0, 0x59, 0x08, 0xc0, 0xb3, 0x90, 0x1e, 0xb7, 0x23, 0x7e, 0xfc, 0x8b, 0x62, - 0x78, 0x88, 0x1e, 0xb8, 0x0e, 0x79, 0x61, 0xa0, 0x4c, 0xdb, 0x1a, 0x03, 0xe2, 0x27, 0x38, 0xc4, - 0x54, 0x80, 0x8d, 0x37, 0xc3, 0xc5, 0x8e, 0xbb, 0x8b, 0xc7, 0x01, 0xf9, 0xb8, 0x68, 0x06, 0x67, - 0xe1, 0xa2, 0xdc, 0xc6, 0x96, 0xb1, 0x37, 0x1e, 0xc2, 0x27, 0x84, 0x28, 0x05, 0x0f, 0x81, 0xa8, - 0x40, 0xae, 0xad, 0x77, 0x9d, 0x3d, 0xbd, 0x35, 0x56, 0x77, 0x7c, 0x92, 0x63, 0x64, 0x3d, 0x26, - 0x2e, 0x91, 0x9e, 0x75, 0x14, 0x98, 0x9f, 0x14, 0x12, 0x09, 0xb0, 0xf1, 0xa1, 0xe7, 0xb8, 0x34, - 0x6c, 0x7e, 0x14, 0xb4, 0x9f, 0x12, 0x43, 0x8f, 0xf1, 0xae, 0x06, 0x11, 0x9f, 0x85, 0xb4, 0x63, - 0xbe, 0x3e, 0x16, 0xcc, 0x3f, 0x12, 0x3d, 0x4d, 0x19, 0x08, 0xf3, 0x2b, 0x70, 0x2a, 0x72, 0x9a, - 0x18, 0x03, 0xec, 0xa7, 0x39, 0xd8, 0x89, 0x88, 0xa9, 0x82, 0x9b, 0x84, 0xa3, 0x42, 0xfe, 0x8c, - 0x30, 0x09, 0xb8, 0x0f, 0x6b, 0x83, 0x2c, 0x5a, 0x1c, 0x7d, 0xe7, 0x68, 0x52, 0xfb, 0xc7, 0x42, - 0x6a, 0x8c, 0x37, 0x24, 0xb5, 0x06, 0x9c, 0xe0, 0x88, 0x47, 0xeb, 0xd7, 0x9f, 0x15, 0x86, 0x95, - 0x71, 0x6f, 0x86, 0x7b, 0xf7, 0xeb, 0x61, 0xce, 0x13, 0xa7, 0xf0, 0x8e, 0x1d, 0xad, 0xad, 0x77, - 0xc6, 0x40, 0xfe, 0x39, 0x8e, 0x2c, 0x2c, 0xbe, 0xe7, 0x5e, 0x3b, 0xab, 0x7a, 0x87, 0x80, 0xbf, - 0x0c, 0x05, 0x01, 0xde, 0xb3, 0xba, 0xd8, 0xb0, 0x77, 0x2d, 0xf3, 0x75, 0xdc, 0x1c, 0x03, 0xfa, - 0x9f, 0xf4, 0x75, 0xd5, 0x66, 0x80, 0x9d, 0x20, 0xd7, 0x40, 0xf6, 0x7c, 0x15, 0xcd, 0x6c, 0x77, - 0xec, 0xae, 0x3b, 0x02, 0xf1, 0x53, 0xa2, 0xa7, 0x3c, 0xbe, 0x1a, 0x65, 0x2b, 0x56, 0x81, 0x9d, - 0x25, 0x19, 0x57, 0x25, 0x3f, 0xcd, 0x81, 0x72, 0x3e, 0x17, 0x37, 0x1c, 0x86, 0xdd, 0xee, 0xe8, - 0xdd, 0x71, 0xec, 0xdf, 0xcf, 0x0b, 0xc3, 0xc1, 0x59, 0xb8, 0xe1, 0x20, 0x1e, 0x1d, 0x99, 0xed, - 0xc7, 0x40, 0xf8, 0x05, 0x61, 0x38, 0x04, 0x0f, 0x87, 0x10, 0x0e, 0xc3, 0x18, 0x10, 0xff, 0x54, - 0x40, 0x08, 0x1e, 0x02, 0xf1, 0x2e, 0x7f, 0xa2, 0xed, 0xe2, 0x5d, 0xd3, 0x71, 0xf9, 0x61, 0xb0, - 0xc3, 0xa1, 0x7e, 0xf1, 0x8b, 0x61, 0x27, 0x4c, 0x0d, 0xb0, 0x12, 0x4b, 0xc4, 0x37, 0x52, 0xe8, - 0x92, 0x6d, 0x74, 0xc5, 0x7e, 0x49, 0x58, 0xa2, 0x00, 0x1b, 0xa9, 0x5b, 0xc0, 0x43, 0x24, 0x62, - 0x37, 0xc8, 0x42, 0x65, 0x0c, 0xb8, 0x7f, 0xd6, 0x57, 0xb9, 0xba, 0xe0, 0x25, 0x98, 0x01, 0xff, - 0xa7, 0x67, 0xdd, 0xc2, 0x07, 0x63, 0x69, 0xe7, 0x2f, 0xf7, 0xf9, 0x3f, 0x9b, 0x8c, 0x93, 0xd9, - 0x90, 0x7c, 0x9f, 0x3f, 0x85, 0x46, 0x9d, 0xf5, 0x2c, 0x7c, 0xcb, 0x97, 0x78, 0x7b, 0xc3, 0xee, - 0x54, 0x71, 0x85, 0x28, 0x79, 0xd8, 0xe9, 0x19, 0x0d, 0xf6, 0xad, 0x5f, 0xf2, 0xf4, 0x3c, 0xe4, - 0xf3, 0x14, 0x97, 0x21, 0x17, 0x72, 0x78, 0x46, 0x43, 0x7d, 0x1b, 0x87, 0xca, 0x06, 0xfd, 0x9d, - 0xe2, 0x93, 0x90, 0x20, 0xce, 0xcb, 0x68, 0xf6, 0xf7, 0x71, 0x76, 0x4a, 0x5e, 0x7c, 0x1e, 0x52, - 0xc2, 0x69, 0x19, 0xcd, 0xfa, 0xed, 0x9c, 0xd5, 0x63, 0x21, 0xec, 0xc2, 0x61, 0x19, 0xcd, 0xfe, - 0x77, 0x05, 0xbb, 0x60, 0x21, 0xec, 0xe3, 0x8b, 0xf0, 0x5f, 0x7d, 0x67, 0x82, 0x4f, 0x3a, 0x42, - 0x76, 0xcf, 0xc2, 0x24, 0xf7, 0x54, 0x46, 0x73, 0x7f, 0x07, 0x2f, 0x5c, 0x70, 0x14, 0x9f, 0x82, - 0x89, 0x31, 0x05, 0xfe, 0xdd, 0x9c, 0x95, 0xd1, 0x17, 0x2b, 0x90, 0x09, 0x78, 0x27, 0xa3, 0xd9, - 0xbf, 0x87, 0xb3, 0x07, 0xb9, 0x48, 0xd5, 0xb9, 0x77, 0x32, 0x1a, 0xe0, 0xef, 0x89, 0xaa, 0x73, - 0x0e, 0x22, 0x36, 0xe1, 0x98, 0x8c, 0xe6, 0xfe, 0x80, 0x90, 0xba, 0x60, 0x29, 0xbe, 0x08, 0x69, - 0x6f, 0xb2, 0x19, 0xcd, 0xff, 0xbd, 0x9c, 0xdf, 0xe7, 0x21, 0x12, 0x08, 0x4c, 0x76, 0xa3, 0x21, - 0xfe, 0xbe, 0x90, 0x40, 0x80, 0x8b, 0x0c, 0xa3, 0x7e, 0x07, 0x66, 0x34, 0xd2, 0xf7, 0x89, 0x61, - 0xd4, 0xe7, 0xbf, 0x90, 0xde, 0xa4, 0x36, 0x7f, 0x34, 0xc4, 0xf7, 0x8b, 0xde, 0xa4, 0xf4, 0xa4, - 0x1a, 0xfd, 0x1e, 0xc1, 0x68, 0x8c, 0x1f, 0x14, 0xd5, 0xe8, 0x73, 0x08, 0x8a, 0x1b, 0x80, 0x06, - 0xbd, 0x81, 0xd1, 0x78, 0x1f, 0xe4, 0x78, 0xd3, 0x03, 0xce, 0x40, 0xf1, 0xdd, 0x70, 0x22, 0xda, - 0x13, 0x18, 0x8d, 0xfa, 0x43, 0x5f, 0xea, 0x5b, 0xbb, 0x05, 0x1d, 0x81, 0x62, 0xc3, 0x9f, 0x52, - 0x82, 0x5e, 0xc0, 0x68, 0xd8, 0x0f, 0x7d, 0x29, 0x6c, 0xb8, 0x83, 0x4e, 0x40, 0xb1, 0x04, 0xe0, - 0x4f, 0xc0, 0xa3, 0xb1, 0x3e, 0xc2, 0xb1, 0x02, 0x4c, 0x64, 0x68, 0xf0, 0xf9, 0x77, 0x34, 0xff, - 0x5d, 0x31, 0x34, 0x38, 0x07, 0x19, 0x1a, 0x62, 0xea, 0x1d, 0xcd, 0xfd, 0x51, 0x31, 0x34, 0x04, - 0x0b, 0xd1, 0xec, 0xc0, 0xec, 0x36, 0x1a, 0xe1, 0x47, 0x84, 0x66, 0x07, 0xb8, 0x8a, 0x6b, 0x30, - 0x3d, 0x30, 0x21, 0x8e, 0x86, 0xfa, 0x51, 0x0e, 0x25, 0xf7, 0xcf, 0x87, 0xc1, 0xc9, 0x8b, 0x4f, - 0x86, 0xa3, 0xd1, 0x7e, 0xac, 0x6f, 0xf2, 0xe2, 0x73, 0x61, 0xf1, 0x59, 0x48, 0x59, 0xbd, 0x56, - 0x8b, 0x0c, 0x1e, 0x74, 0xf8, 0x69, 0xdf, 0xc2, 0x7f, 0xff, 0x0a, 0x97, 0x8e, 0x60, 0x28, 0x3e, - 0x09, 0x13, 0xb8, 0xbd, 0x8d, 0x9b, 0xa3, 0x38, 0xff, 0xe8, 0x2b, 0xc2, 0x60, 0x12, 0xea, 0xe2, - 0x8b, 0x00, 0x2c, 0x34, 0x42, 0xb7, 0xe1, 0x47, 0xf0, 0x7e, 0xe1, 0x2b, 0xfc, 0x78, 0x9d, 0xcf, - 0xe2, 0x03, 0xb0, 0xc3, 0x7a, 0x87, 0x03, 0x7c, 0x31, 0x0c, 0x40, 0x7b, 0xe4, 0x19, 0x98, 0x7c, - 0xcd, 0xb1, 0x2d, 0x57, 0xdf, 0x1d, 0xc5, 0xfd, 0xc7, 0x9c, 0x5b, 0xd0, 0x13, 0x81, 0xb5, 0xed, - 0x2e, 0x76, 0xf5, 0x5d, 0x67, 0x14, 0xef, 0x9f, 0x70, 0x5e, 0x8f, 0x81, 0x30, 0x1b, 0xba, 0xe3, - 0x8e, 0xd3, 0xee, 0xff, 0x21, 0x98, 0x05, 0x03, 0xa9, 0x34, 0xf9, 0xfb, 0x16, 0x3e, 0x18, 0xc5, - 0xfb, 0xa7, 0xa2, 0xd2, 0x9c, 0xbe, 0xf8, 0x3c, 0xa4, 0xc9, 0x9f, 0xec, 0xcc, 0xec, 0x08, 0xe6, - 0x3f, 0xe3, 0xcc, 0x3e, 0x07, 0x29, 0xd9, 0x71, 0x9b, 0xae, 0x39, 0x5a, 0xd8, 0x7f, 0xce, 0x7b, - 0x5a, 0xd0, 0x17, 0x4b, 0x90, 0x71, 0xdc, 0x66, 0xb3, 0xc7, 0xfd, 0xd3, 0x11, 0xec, 0xff, 0xf3, - 0x2b, 0x5e, 0xc8, 0xc2, 0xe3, 0x21, 0xbd, 0x7d, 0xe7, 0x96, 0xdb, 0xb1, 0xe9, 0x7e, 0xcb, 0x28, - 0x84, 0x2f, 0x71, 0x84, 0x00, 0x4b, 0xb1, 0x02, 0x59, 0xd2, 0x16, 0x71, 0x17, 0x61, 0x14, 0xc4, - 0x97, 0xb9, 0x00, 0x42, 0x4c, 0xe5, 0x6f, 0xfe, 0xb5, 0xcf, 0x9e, 0x91, 0x3e, 0xf3, 0xd9, 0x33, - 0xd2, 0xef, 0x7d, 0xf6, 0x8c, 0xf4, 0x81, 0xcf, 0x9d, 0x39, 0xf6, 0x99, 0xcf, 0x9d, 0x39, 0xf6, - 0xdb, 0x9f, 0x3b, 0x73, 0x2c, 0x3a, 0x4a, 0x0c, 0xd7, 0xed, 0xeb, 0x36, 0x8b, 0x0f, 0xbf, 0xfa, - 0xe0, 0xae, 0xe9, 0xee, 0xf5, 0xb6, 0x17, 0x0d, 0xbb, 0x7d, 0xc9, 0xb0, 0x9d, 0xb6, 0xed, 0x5c, - 0x0a, 0xc7, 0x75, 0xe9, 0x5f, 0xf0, 0xbf, 0x25, 0xb2, 0x66, 0x0e, 0x87, 0x73, 0x75, 0xeb, 0x60, - 0xd8, 0x65, 0xca, 0x6b, 0x10, 0x2f, 0x59, 0x07, 0xe8, 0x14, 0x33, 0x70, 0x5a, 0xaf, 0xdb, 0xe2, - 0x07, 0x37, 0x27, 0xc9, 0xf7, 0x66, 0xb7, 0x85, 0x66, 0xfd, 0xd3, 0xd5, 0xd2, 0x85, 0x2c, 0x3f, - 0x32, 0x5d, 0xfe, 0x1e, 0xe9, 0x68, 0x2d, 0x49, 0x95, 0xac, 0x03, 0xda, 0x90, 0x0d, 0xe9, 0xd5, - 0x47, 0x47, 0xc6, 0xb9, 0x6f, 0x59, 0xf6, 0x1d, 0x8b, 0x54, 0xbb, 0xb3, 0x2d, 0x62, 0xdc, 0x67, - 0xfa, 0x63, 0xdc, 0xef, 0xc6, 0xad, 0xd6, 0x4b, 0x84, 0xae, 0x41, 0x58, 0xb6, 0x93, 0xec, 0x8e, - 0x00, 0x7c, 0x5f, 0x0c, 0xce, 0x0c, 0x84, 0xb3, 0xb9, 0x12, 0x0c, 0x13, 0x42, 0x11, 0x52, 0x4b, - 0x42, 0xb7, 0x0a, 0x30, 0xe9, 0x60, 0xc3, 0xb6, 0x9a, 0x0e, 0x15, 0x44, 0x5c, 0x15, 0x9f, 0x44, - 0x10, 0x96, 0x6e, 0xd9, 0x0e, 0x3f, 0xfa, 0xcc, 0x3e, 0xca, 0x1f, 0x3e, 0xa2, 0x20, 0x72, 0xa2, - 0x24, 0x21, 0x8d, 0xcb, 0x63, 0x4a, 0x43, 0x34, 0x22, 0x14, 0xf9, 0x1f, 0x57, 0x2a, 0x3f, 0x18, - 0x83, 0xf9, 0x7e, 0xa9, 0x90, 0x91, 0xe5, 0xb8, 0x7a, 0xbb, 0x33, 0x4c, 0x2c, 0xcf, 0x42, 0xba, - 0x21, 0x68, 0x8e, 0x2c, 0x97, 0xbb, 0x47, 0x94, 0xcb, 0x94, 0x57, 0x94, 0x10, 0xcc, 0x95, 0x31, - 0x05, 0xe3, 0xb5, 0xe3, 0x9e, 0x24, 0xf3, 0xe1, 0x34, 0x9c, 0x62, 0xc3, 0x49, 0x63, 0x43, 0x89, - 0x7d, 0x70, 0x99, 0x64, 0x83, 0x59, 0xa3, 0xf7, 0x49, 0x94, 0x97, 0x60, 0xa6, 0x46, 0xac, 0x05, - 0x59, 0x05, 0xf9, 0x3b, 0x3c, 0x91, 0xa7, 0xc3, 0x17, 0x42, 0x0e, 0x3f, 0xdf, 0xdf, 0x0a, 0x26, - 0x29, 0xdf, 0x22, 0x81, 0x5c, 0x37, 0xf4, 0x96, 0xde, 0x7d, 0xab, 0x50, 0xe8, 0x29, 0x00, 0x76, - 0xdc, 0xc3, 0xbb, 0xb8, 0x39, 0x75, 0xa5, 0xb0, 0x18, 0x6c, 0xdc, 0x22, 0x2b, 0x89, 0x1e, 0xa1, - 0x4a, 0x53, 0x5a, 0xf2, 0xe7, 0xc5, 0x97, 0x01, 0xfc, 0x0c, 0x74, 0x1a, 0x4e, 0xd6, 0x2b, 0xa5, - 0x95, 0x92, 0x2a, 0x0e, 0x09, 0xd5, 0x37, 0xaa, 0x15, 0x76, 0xcd, 0xea, 0x18, 0x3a, 0x01, 0x28, - 0x98, 0xe9, 0x1d, 0x6a, 0x3a, 0x0e, 0xd3, 0xc1, 0x74, 0x76, 0xe7, 0x25, 0x56, 0xbc, 0x01, 0x79, - 0x76, 0x20, 0x5f, 0xd3, 0x9b, 0x4d, 0xdc, 0xd4, 0x4c, 0x0b, 0x8d, 0x38, 0xdf, 0x5e, 0xf8, 0xf5, - 0xff, 0x32, 0x41, 0x9b, 0x96, 0x63, 0x8c, 0x25, 0xc2, 0x57, 0xb3, 0x88, 0xcf, 0x69, 0xb6, 0x3b, - 0x2d, 0x4c, 0xf7, 0x30, 0x35, 0x53, 0xc8, 0x7f, 0xb4, 0x3b, 0x43, 0xf0, 0xe2, 0x17, 0xd2, 0xea, - 0x8c, 0xcf, 0xee, 0xf5, 0x5e, 0xf1, 0x25, 0x90, 0xc5, 0xc1, 0x51, 0xaf, 0x82, 0x23, 0x11, 0x7f, - 0x83, 0xd7, 0x50, 0x44, 0x33, 0x44, 0x15, 0x57, 0x60, 0x5a, 0x37, 0x0c, 0xdc, 0x09, 0xd5, 0x6f, - 0xc4, 0x0c, 0x22, 0x5a, 0x2b, 0x73, 0x4e, 0xbf, 0x6a, 0x4f, 0x41, 0xd2, 0xa1, 0x9d, 0x32, 0x0a, - 0x42, 0x54, 0x87, 0x93, 0x17, 0xab, 0x30, 0xc5, 0xd4, 0xc0, 0x6b, 0xd1, 0x08, 0x80, 0x7f, 0xcf, - 0x01, 0xb2, 0x94, 0x4d, 0xb4, 0xc6, 0x82, 0x69, 0x76, 0x6b, 0x11, 0x07, 0x5a, 0x73, 0x78, 0x14, - 0xe5, 0x9f, 0x7f, 0xea, 0x71, 0xba, 0x6f, 0x7c, 0x36, 0xac, 0x74, 0x11, 0x83, 0x45, 0x95, 0x39, - 0xb6, 0xdf, 0x5e, 0x0c, 0x53, 0xa2, 0x3c, 0xde, 0xee, 0xc3, 0x0b, 0xfb, 0x17, 0xbc, 0xb0, 0x33, - 0x51, 0x1a, 0x1e, 0x28, 0x29, 0xc7, 0x51, 0x59, 0x46, 0xb1, 0x0c, 0xb9, 0x1d, 0xb3, 0x15, 0xe8, - 0xee, 0xc3, 0x4b, 0xf9, 0x97, 0x9f, 0x7a, 0x9c, 0x0d, 0x34, 0xc2, 0xc4, 0x45, 0x53, 0xae, 0x0e, - 0xb3, 0x7a, 0xaf, 0x3e, 0x32, 0x38, 0x7f, 0xb3, 0xff, 0x1e, 0xa3, 0xe8, 0xcf, 0x06, 0xab, 0xea, - 0x5b, 0xa7, 0x04, 0x4c, 0xeb, 0x6d, 0xd3, 0xb2, 0x2f, 0xd1, 0x7f, 0xb9, 0x55, 0x9a, 0xa0, 0x1f, - 0x63, 0x6c, 0xdb, 0x5e, 0x63, 0xc6, 0x62, 0xb4, 0xde, 0xfe, 0xd9, 0x77, 0xfd, 0xc4, 0x84, 0x6f, - 0x50, 0x8a, 0xab, 0xbe, 0xee, 0x63, 0xcb, 0xb0, 0x9b, 0x63, 0xc5, 0x71, 0xfe, 0x5c, 0x60, 0x88, - 0x08, 0x60, 0x95, 0xb3, 0x16, 0x9f, 0x83, 0x94, 0x07, 0x33, 0xca, 0x77, 0x13, 0x20, 0x1e, 0x07, - 0xf1, 0xdc, 0x98, 0xd2, 0x8e, 0xe3, 0xa7, 0x7f, 0x49, 0xf0, 0x33, 0x1b, 0xb6, 0x46, 0x5a, 0x73, - 0x1d, 0xa6, 0x9a, 0xb6, 0xe5, 0x6a, 0x76, 0xdb, 0x74, 0x71, 0xbb, 0xe3, 0x8e, 0xf4, 0x7c, 0xbf, - 0xcc, 0x40, 0x52, 0x6a, 0x8e, 0xf0, 0xad, 0x0b, 0x36, 0x52, 0x13, 0x76, 0x2f, 0x72, 0x9c, 0x9a, - 0xfc, 0x85, 0x57, 0x13, 0xca, 0x43, 0x6a, 0x72, 0x4f, 0xda, 0xe1, 0x34, 0x6f, 0xf1, 0xe9, 0xce, - 0xdd, 0x67, 0x5a, 0xe0, 0x69, 0xc7, 0xc7, 0xe3, 0x70, 0x86, 0x13, 0x6f, 0xeb, 0x0e, 0xbe, 0x74, - 0xfb, 0xf2, 0x36, 0x76, 0xf5, 0xcb, 0x97, 0x0c, 0xdb, 0x14, 0xbe, 0xce, 0x0c, 0x9f, 0xce, 0x48, - 0xfe, 0x22, 0xcf, 0x9f, 0x8b, 0x3c, 0x10, 0x30, 0x37, 0x7c, 0x1a, 0x9c, 0x1b, 0xd4, 0x41, 0xa5, - 0x05, 0x89, 0x8a, 0x6d, 0x5a, 0x64, 0xf6, 0x6f, 0x62, 0xcb, 0x6e, 0xf3, 0x09, 0x89, 0x7d, 0xa0, - 0x1b, 0x90, 0xd4, 0xdb, 0x76, 0xcf, 0x72, 0xd9, 0x64, 0x54, 0x7e, 0xfc, 0xd7, 0xde, 0x9c, 0x3f, - 0xf6, 0x3b, 0x6f, 0xce, 0x1f, 0x67, 0xb0, 0x4e, 0xf3, 0xd6, 0xa2, 0x69, 0x5f, 0x6a, 0xeb, 0xee, - 0x1e, 0x31, 0x01, 0xbf, 0xf5, 0xe9, 0xc7, 0x80, 0x97, 0x57, 0xb3, 0xdc, 0x4f, 0xfc, 0xe1, 0xcf, - 0x5e, 0x94, 0x54, 0xce, 0x5f, 0x4c, 0x7c, 0xfe, 0x63, 0xf3, 0x92, 0xd2, 0x81, 0xc9, 0x25, 0x6c, - 0x1c, 0x52, 0x60, 0xad, 0xaf, 0xc0, 0xcb, 0xbc, 0xc0, 0xd3, 0x83, 0x05, 0xb2, 0x23, 0x8d, 0x4b, - 0xd8, 0x08, 0x14, 0xbb, 0x84, 0x8d, 0x70, 0x89, 0xe5, 0xa5, 0xdf, 0xfe, 0xfd, 0x33, 0xc7, 0xde, - 0xfb, 0xd9, 0x33, 0xc7, 0x86, 0x76, 0x99, 0x32, 0xba, 0xcb, 0xbc, 0x9e, 0xfa, 0x64, 0x82, 0xf4, - 0x54, 0x1b, 0xbb, 0xdb, 0x3b, 0xee, 0x25, 0xa3, 0x7b, 0xd0, 0x71, 0xed, 0x4b, 0xb7, 0x2f, 0x93, - 0x91, 0x6b, 0xef, 0xf0, 0x9e, 0x42, 0x22, 0x7f, 0x91, 0xe5, 0x2f, 0xde, 0x1e, 0xd2, 0x51, 0xca, - 0x0e, 0x4c, 0x6c, 0x10, 0x46, 0x22, 0x0a, 0xd7, 0x76, 0xf5, 0x16, 0xf7, 0xc8, 0xd8, 0x07, 0x49, - 0x65, 0xf7, 0x76, 0x63, 0x2c, 0xd5, 0x14, 0x57, 0x76, 0x5b, 0x58, 0xdf, 0x61, 0xd7, 0x9f, 0xe2, - 0xd4, 0x95, 0x4f, 0x91, 0x04, 0x7a, 0xd3, 0x69, 0x16, 0x26, 0xf4, 0x1e, 0x3b, 0x54, 0x14, 0x27, - 0x3e, 0x3e, 0xfd, 0x50, 0x56, 0x60, 0x92, 0x9f, 0x2d, 0x40, 0x32, 0xc4, 0x6f, 0xe1, 0x03, 0x5a, - 0x4e, 0x56, 0x25, 0x7f, 0xa2, 0x4b, 0x30, 0x41, 0x6b, 0xcf, 0xef, 0x75, 0x9e, 0x5a, 0x1c, 0xac, - 0xfe, 0x22, 0xad, 0xa5, 0xca, 0xe8, 0x94, 0x9b, 0x90, 0x5a, 0xb2, 0x89, 0x02, 0x85, 0xe1, 0xd2, - 0x0c, 0x8e, 0x56, 0xba, 0xd3, 0xe3, 0xdd, 0xa7, 0xb2, 0x0f, 0x74, 0x02, 0x92, 0xec, 0x3e, 0x1c, - 0x3f, 0x19, 0xc5, 0xbf, 0x94, 0x0a, 0x4c, 0x52, 0xec, 0xf5, 0x8e, 0x77, 0x07, 0x5d, 0x0a, 0xdc, - 0x41, 0xe7, 0xf0, 0x31, 0xbf, 0xb6, 0x08, 0x12, 0x4d, 0xdd, 0xd5, 0x79, 0xc3, 0xe9, 0xdf, 0xca, - 0x8b, 0x90, 0xe2, 0x20, 0x0e, 0x7a, 0x02, 0xe2, 0x76, 0xc7, 0xe1, 0x67, 0x9b, 0x4e, 0x0f, 0x6d, - 0xcb, 0x7a, 0xa7, 0x9c, 0x20, 0x8a, 0xa5, 0x12, 0xea, 0xf2, 0xea, 0x50, 0xd5, 0x78, 0x22, 0xa4, - 0x1a, 0xa2, 0xdb, 0xc5, 0x1f, 0x7a, 0xc7, 0xbc, 0x34, 0xa8, 0x0c, 0x9e, 0xae, 0xfc, 0x2f, 0x09, - 0xee, 0x8f, 0xd0, 0x95, 0x5b, 0xf8, 0xc0, 0x39, 0xb2, 0xaa, 0xbc, 0x0c, 0xe9, 0x0d, 0xfa, 0xba, - 0xcc, 0x4b, 0xf8, 0x00, 0xcd, 0xc1, 0x24, 0x6e, 0x5e, 0x79, 0xf2, 0xc9, 0xcb, 0xcf, 0xb0, 0x8e, - 0xbc, 0x71, 0x4c, 0x15, 0x09, 0xe8, 0x0c, 0xa4, 0x1d, 0x6c, 0x74, 0xae, 0x3c, 0x79, 0xed, 0xd6, - 0x65, 0x26, 0xb8, 0x1b, 0xc7, 0x54, 0x3f, 0xa9, 0x98, 0x22, 0x83, 0xe2, 0xf3, 0x3f, 0x32, 0x2f, - 0x95, 0x27, 0x20, 0xee, 0xf4, 0xda, 0xef, 0x54, 0xe3, 0xff, 0x22, 0x09, 0x67, 0xbd, 0x6c, 0x66, - 0xf6, 0x6e, 0x5f, 0xbe, 0x74, 0x5b, 0x6f, 0x99, 0x4d, 0xdd, 0x7f, 0x13, 0x68, 0xda, 0x13, 0x00, - 0x25, 0x19, 0xda, 0xfe, 0xb9, 0xc3, 0x05, 0xa9, 0x7c, 0x5a, 0x82, 0xec, 0x96, 0xc0, 0xae, 0x63, - 0x17, 0x3d, 0x07, 0xe0, 0x95, 0x25, 0xd4, 0xe1, 0xbe, 0xc5, 0x81, 0xd2, 0x16, 0x3d, 0x26, 0x35, - 0x40, 0x8f, 0x9e, 0x86, 0x54, 0xa7, 0x6b, 0x77, 0x6c, 0x87, 0xdf, 0x8f, 0x1d, 0xc5, 0xeb, 0x51, - 0xa3, 0x47, 0x01, 0xd1, 0xc1, 0xab, 0xdd, 0xb6, 0x5d, 0xd3, 0xda, 0xd5, 0x3a, 0xf6, 0x1d, 0xfe, - 0xec, 0x40, 0x5c, 0x95, 0x69, 0xce, 0x16, 0xcd, 0xd8, 0x20, 0xe9, 0xca, 0xa7, 0x24, 0x48, 0x7b, - 0x28, 0x64, 0x65, 0xa6, 0x37, 0x9b, 0x5d, 0xec, 0x38, 0x7c, 0x7c, 0x8a, 0x4f, 0xf4, 0x1c, 0x4c, - 0x76, 0x7a, 0xdb, 0x9a, 0x18, 0x0b, 0x99, 0x2b, 0xf7, 0x47, 0x6a, 0xb6, 0x50, 0x10, 0xae, 0xdb, - 0xc9, 0x4e, 0x6f, 0x9b, 0xa8, 0xcb, 0x59, 0xc8, 0x46, 0xd4, 0x26, 0x73, 0xdb, 0xaf, 0x08, 0x7d, - 0xd5, 0x88, 0x37, 0x41, 0xeb, 0x74, 0x4d, 0xbb, 0x6b, 0xba, 0x07, 0xf4, 0xe8, 0x5d, 0x5c, 0x95, - 0x45, 0xc6, 0x06, 0x4f, 0x57, 0x5a, 0x90, 0xaf, 0x53, 0x47, 0xdb, 0xaf, 0xfa, 0x35, 0xbf, 0x82, - 0xd2, 0x18, 0x15, 0x1c, 0x5a, 0xb5, 0xd8, 0x40, 0xd5, 0x2e, 0xfe, 0x57, 0x09, 0x32, 0xe5, 0x96, - 0x6d, 0xdc, 0xaa, 0x2d, 0x2d, 0xb7, 0xf4, 0x5d, 0x74, 0x19, 0x8e, 0x97, 0x57, 0xd6, 0x2b, 0x2f, - 0x69, 0xb5, 0x25, 0x6d, 0x79, 0xa5, 0x74, 0xdd, 0x3f, 0xec, 0x3b, 0x77, 0xe2, 0x8d, 0xbb, 0x0b, - 0x28, 0x40, 0xbb, 0x69, 0xd1, 0x85, 0x25, 0xba, 0x04, 0xb3, 0x61, 0x96, 0x52, 0xb9, 0x5e, 0x5d, - 0x6b, 0xc8, 0xd2, 0xdc, 0xf1, 0x37, 0xee, 0x2e, 0x4c, 0x07, 0x38, 0x4a, 0xdb, 0x0e, 0xb6, 0xdc, - 0x41, 0x86, 0xca, 0xfa, 0xea, 0x6a, 0xad, 0x21, 0xc7, 0x06, 0x18, 0x2a, 0x76, 0xbb, 0x6d, 0xba, - 0xe8, 0x61, 0x98, 0x0e, 0x33, 0xac, 0xd5, 0x56, 0xe4, 0xf8, 0x1c, 0x7a, 0xe3, 0xee, 0xc2, 0x54, - 0x80, 0x7a, 0xcd, 0x6c, 0xcd, 0xa5, 0xde, 0xff, 0x63, 0x67, 0x8e, 0x7d, 0xe2, 0x1f, 0x9e, 0x91, - 0xca, 0x2b, 0x43, 0x47, 0xde, 0x95, 0xf1, 0x47, 0x9e, 0x18, 0x5a, 0xde, 0xc0, 0xfb, 0x68, 0x0c, - 0xe6, 0xbd, 0xdc, 0xdb, 0xb8, 0xeb, 0x98, 0xb6, 0x45, 0x46, 0x0b, 0x53, 0x5b, 0xcf, 0x99, 0xe0, - 0x9d, 0xc3, 0x09, 0x86, 0x1b, 0x9e, 0xe7, 0x21, 0x5e, 0xea, 0x74, 0xd0, 0x1c, 0x1d, 0x11, 0xae, - 0x6d, 0xd8, 0x6c, 0x92, 0x4a, 0xa8, 0xde, 0x37, 0xc9, 0x73, 0xec, 0x1d, 0xf7, 0x8e, 0xde, 0xf5, - 0x9e, 0xa9, 0x10, 0xdf, 0xca, 0x33, 0x90, 0xae, 0xd8, 0x96, 0x83, 0x2d, 0xa7, 0x47, 0x03, 0x0c, - 0xdb, 0x44, 0x18, 0x1c, 0x81, 0x7d, 0x10, 0x23, 0xaf, 0x77, 0x3a, 0x94, 0x33, 0xa1, 0x92, 0x3f, - 0xf9, 0xc4, 0xbd, 0x36, 0x54, 0x3c, 0x57, 0xc7, 0x17, 0x8f, 0x2f, 0x00, 0x4f, 0x40, 0xdf, 0x7f, - 0x7f, 0xc0, 0x2c, 0x7b, 0x96, 0x29, 0x28, 0x9e, 0x08, 0xab, 0x34, 0x62, 0xd2, 0x9f, 0x1b, 0x6d, - 0xeb, 0xe6, 0x46, 0xf5, 0xca, 0x10, 0xcb, 0x37, 0x2a, 0xdc, 0xa3, 0x3c, 0x03, 0xb9, 0x0d, 0xbd, - 0xeb, 0xd6, 0xb1, 0x7b, 0x03, 0xeb, 0x4d, 0xdc, 0x0d, 0x7b, 0x13, 0x39, 0xe1, 0x4d, 0x20, 0x48, - 0x50, 0x97, 0x81, 0x4d, 0xa6, 0xf4, 0x6f, 0xc5, 0x84, 0x04, 0x3d, 0x7b, 0xed, 0x79, 0x1a, 0x9c, - 0x83, 0x79, 0x1a, 0xa4, 0xbb, 0x0e, 0x5c, 0xec, 0x88, 0x80, 0x21, 0xfd, 0x40, 0x4f, 0x0a, 0x7f, - 0x21, 0x3e, 0xc2, 0x5f, 0xe0, 0x56, 0x88, 0x7b, 0x0d, 0x6d, 0x98, 0xe4, 0x03, 0xc1, 0xab, 0x89, - 0xe4, 0xd7, 0x04, 0xad, 0x41, 0xbe, 0xa3, 0x77, 0x5d, 0x7a, 0xb5, 0x73, 0x8f, 0x36, 0x83, 0x5b, - 0xba, 0x85, 0x08, 0xc3, 0x1b, 0x6a, 0x2e, 0x2f, 0x26, 0xd7, 0x09, 0x26, 0x2a, 0x9f, 0x4f, 0x40, - 0x92, 0x8b, 0xe3, 0x05, 0x98, 0xe4, 0x02, 0xe7, 0xb6, 0xe9, 0xcc, 0x62, 0x84, 0xfa, 0x2f, 0x7a, - 0x6a, 0xca, 0x01, 0x05, 0x13, 0x7a, 0x08, 0x52, 0xc6, 0x9e, 0x6e, 0x5a, 0x9a, 0xd9, 0xe4, 0x3e, - 0x69, 0xe6, 0xb3, 0x6f, 0xce, 0x4f, 0x56, 0x48, 0x5a, 0x6d, 0x49, 0x9d, 0xa4, 0x99, 0xb5, 0x26, - 0xf1, 0x71, 0xf6, 0xb0, 0xb9, 0xbb, 0xe7, 0x72, 0x03, 0xcb, 0xbf, 0xd0, 0xd3, 0x90, 0x20, 0x5d, - 0xc6, 0xaf, 0xfe, 0xcf, 0x0d, 0x2c, 0x36, 0xbc, 0x78, 0x59, 0x39, 0x45, 0x0a, 0xfe, 0xc0, 0x7f, - 0x9b, 0x97, 0x54, 0xca, 0x81, 0x96, 0x20, 0xd7, 0xd2, 0x1d, 0x57, 0xa3, 0xe3, 0x84, 0x14, 0x3f, - 0xc1, 0x21, 0x06, 0x45, 0xc2, 0x65, 0xcb, 0xeb, 0x9e, 0x21, 0x6c, 0x2c, 0xa9, 0x89, 0x2e, 0x80, - 0x4c, 0x51, 0x0c, 0x6a, 0xaa, 0x98, 0xdf, 0x98, 0xa4, 0xa2, 0x9f, 0x22, 0xe9, 0xcc, 0x82, 0x51, - 0xef, 0xf1, 0x34, 0xa4, 0xe9, 0x6d, 0x63, 0x4a, 0xc2, 0x0e, 0xfd, 0xa7, 0x48, 0x02, 0xcd, 0x3c, - 0x0f, 0x79, 0x7f, 0x86, 0x64, 0x24, 0x29, 0x86, 0xe2, 0x27, 0x53, 0xc2, 0xc7, 0x61, 0xd6, 0xc2, - 0xfb, 0xf4, 0x1a, 0x42, 0x88, 0x3a, 0x4d, 0xa9, 0x11, 0xc9, 0xdb, 0x0a, 0x73, 0x3c, 0x08, 0x53, - 0x86, 0x90, 0x3e, 0xa3, 0x05, 0x4a, 0x9b, 0xf3, 0x52, 0x29, 0xd9, 0x29, 0x48, 0xe9, 0x9d, 0x0e, - 0x23, 0xc8, 0xf0, 0x09, 0xb2, 0xd3, 0xa1, 0x59, 0x17, 0x61, 0x9a, 0xb6, 0xb1, 0x8b, 0x9d, 0x5e, - 0xcb, 0xe5, 0x20, 0x59, 0x4a, 0x93, 0x27, 0x19, 0x2a, 0x4b, 0xa7, 0xb4, 0xe7, 0x20, 0x87, 0x6f, - 0x9b, 0x4d, 0x6c, 0x19, 0x98, 0xd1, 0xe5, 0x28, 0x5d, 0x56, 0x24, 0x52, 0xa2, 0x87, 0xc1, 0x9b, - 0xf7, 0x34, 0x31, 0x29, 0x4f, 0x31, 0x3c, 0x91, 0x5e, 0x62, 0xc9, 0x4a, 0x01, 0x12, 0x4b, 0xba, - 0xab, 0x13, 0x3b, 0xe6, 0xee, 0x33, 0x5f, 0x23, 0xab, 0x92, 0x3f, 0x95, 0x5f, 0x8a, 0x43, 0x62, - 0xcb, 0x76, 0x31, 0xba, 0x1a, 0xf0, 0x6d, 0xa7, 0x22, 0x55, 0xba, 0x6e, 0xee, 0x5a, 0xb8, 0xb9, - 0xea, 0xec, 0x06, 0xde, 0x06, 0xf2, 0x15, 0x2a, 0x16, 0x52, 0xa8, 0x59, 0x98, 0xe8, 0xda, 0x3d, - 0xab, 0x29, 0xce, 0xcb, 0xd3, 0x0f, 0xb4, 0x0c, 0x29, 0x4f, 0x4f, 0x12, 0x23, 0xf5, 0x24, 0x4f, - 0xf4, 0x84, 0xa8, 0x31, 0x4f, 0x50, 0x27, 0xb7, 0xb9, 0xba, 0x94, 0x21, 0xed, 0x59, 0x18, 0x4f, - 0xe1, 0xc6, 0xd1, 0x59, 0x9f, 0x8d, 0xb8, 0x13, 0x5e, 0xef, 0x7b, 0xe2, 0x63, 0x3a, 0x27, 0x7b, - 0x19, 0x5c, 0x7e, 0x21, 0xc5, 0xe2, 0x0f, 0x15, 0x4d, 0xd2, 0x86, 0xf9, 0x8a, 0xc5, 0x1e, 0x2b, - 0xba, 0x0f, 0xd2, 0x8e, 0xb9, 0x6b, 0xe9, 0x6e, 0xaf, 0x8b, 0xb9, 0xee, 0xf9, 0x09, 0x24, 0xd7, - 0xbf, 0x3c, 0xc2, 0x74, 0x2d, 0xf0, 0xe2, 0xdd, 0x25, 0x98, 0xf1, 0xdf, 0x9a, 0xf3, 0x51, 0x98, - 0x9e, 0x21, 0x2f, 0xab, 0x2e, 0x72, 0x94, 0x7f, 0x2d, 0x41, 0x92, 0x4f, 0xee, 0x7e, 0x3f, 0x48, - 0xd1, 0xfd, 0x10, 0x1b, 0xd6, 0x0f, 0xf1, 0xb7, 0xd4, 0x0f, 0xe0, 0xd5, 0xd3, 0xe1, 0xef, 0xd1, - 0x44, 0x79, 0xa1, 0xac, 0x92, 0x75, 0x73, 0x97, 0x8f, 0xfd, 0x00, 0x97, 0xf2, 0xa6, 0x44, 0xa6, - 0x5f, 0x9e, 0x8f, 0xca, 0x90, 0x13, 0x35, 0xd3, 0x76, 0x5a, 0xfa, 0x2e, 0x57, 0xc7, 0x33, 0xc3, - 0xab, 0x47, 0x7c, 0x16, 0x35, 0xc3, 0x6b, 0x44, 0xbd, 0xaf, 0xc8, 0x9e, 0x8d, 0x0d, 0xe9, 0xd9, - 0x90, 0x2a, 0xc5, 0xef, 0x4d, 0x95, 0x42, 0x9d, 0x9e, 0xe8, 0xeb, 0x74, 0xe5, 0x73, 0x12, 0x7f, - 0xec, 0xae, 0xc9, 0x2e, 0xbf, 0xfc, 0x95, 0xf5, 0xd6, 0xd7, 0x73, 0xfd, 0x6a, 0xe2, 0xa6, 0x36, - 0xd0, 0x6d, 0x0f, 0x44, 0x40, 0x86, 0x6b, 0xed, 0x77, 0x1f, 0x12, 0x30, 0x75, 0xbf, 0x1b, 0x7f, - 0x3e, 0x06, 0xd3, 0x03, 0xf4, 0x7f, 0x0d, 0xbb, 0x33, 0x3c, 0x86, 0x27, 0xc6, 0x1c, 0xc3, 0xc9, - 0xa1, 0x63, 0xf8, 0xe7, 0x63, 0x34, 0x32, 0xd0, 0xb1, 0x1d, 0xbd, 0xf5, 0x55, 0xb1, 0xc1, 0xa7, - 0x21, 0xdd, 0xb1, 0x5b, 0x1a, 0xcb, 0x61, 0x37, 0x97, 0x52, 0x1d, 0xbb, 0xa5, 0x0e, 0xa8, 0xda, - 0xc4, 0xdb, 0x65, 0xa0, 0x93, 0x6f, 0x43, 0x37, 0x4c, 0xf6, 0x8f, 0x2a, 0x17, 0xb2, 0x4c, 0x16, - 0xdc, 0x83, 0xba, 0x4c, 0x84, 0x40, 0x7d, 0x32, 0xa9, 0xdf, 0xe7, 0xf3, 0xea, 0xcd, 0x48, 0x55, - 0x4e, 0x48, 0x58, 0x98, 0xbf, 0x31, 0x18, 0x56, 0xea, 0xb3, 0x5c, 0x2a, 0x27, 0x54, 0x3e, 0x28, - 0x01, 0xac, 0x10, 0xe1, 0xd2, 0x16, 0x13, 0xe7, 0xc7, 0xa1, 0x95, 0xd0, 0x42, 0x65, 0xcf, 0x0f, - 0xed, 0x38, 0x5e, 0x83, 0xac, 0x13, 0xac, 0xfa, 0x12, 0xe4, 0x7c, 0x05, 0x77, 0xb0, 0xa8, 0xce, - 0xfc, 0x61, 0xcb, 0xf9, 0x3a, 0x76, 0xd5, 0xec, 0xed, 0xc0, 0x97, 0xf2, 0x6f, 0x24, 0x48, 0xd3, - 0x5a, 0xad, 0x62, 0x57, 0x0f, 0x75, 0xa4, 0xf4, 0x16, 0x3a, 0xf2, 0x7e, 0x00, 0x86, 0xe3, 0x98, - 0xaf, 0x63, 0xae, 0x5f, 0x69, 0x9a, 0x52, 0x37, 0x5f, 0xc7, 0xe8, 0x29, 0x4f, 0xea, 0xf1, 0x11, - 0x52, 0x17, 0xeb, 0x7d, 0x2e, 0xfb, 0x93, 0x30, 0x49, 0x5f, 0x66, 0xdd, 0x77, 0xf8, 0x12, 0x3e, - 0x69, 0xf5, 0xda, 0x8d, 0x7d, 0x47, 0xb9, 0x05, 0x93, 0x8d, 0x7d, 0x16, 0x71, 0x3c, 0x0d, 0xe9, - 0xae, 0x6d, 0x73, 0x6f, 0x90, 0x39, 0xe2, 0x29, 0x92, 0x40, 0x9d, 0x1f, 0x11, 0x64, 0x8b, 0xf9, - 0x41, 0x36, 0x3f, 0x4c, 0x18, 0x1f, 0x2f, 0x4c, 0x48, 0xd6, 0xed, 0xb9, 0xd0, 0x88, 0x42, 0x8f, - 0xc2, 0xc9, 0x7a, 0xed, 0xfa, 0x5a, 0x75, 0x49, 0x5b, 0xad, 0x5f, 0xef, 0x7b, 0x9d, 0x60, 0x2e, - 0xff, 0xc6, 0xdd, 0x85, 0x0c, 0x5f, 0xb0, 0x0f, 0xa3, 0xde, 0x50, 0xab, 0x5b, 0xeb, 0x8d, 0xaa, - 0x2c, 0x31, 0xea, 0x8d, 0x2e, 0xbe, 0x6d, 0xbb, 0xec, 0xed, 0xe3, 0xc7, 0xe1, 0x54, 0x04, 0xb5, - 0xb7, 0x6c, 0x9f, 0x7e, 0xe3, 0xee, 0x42, 0x6e, 0xa3, 0x8b, 0x99, 0xaa, 0x51, 0x8e, 0x45, 0x28, - 0x0c, 0x72, 0xac, 0x6f, 0xac, 0xd7, 0x4b, 0x2b, 0xf2, 0xc2, 0x9c, 0xfc, 0xc6, 0xdd, 0x85, 0xac, - 0xb0, 0x1d, 0x84, 0xfe, 0x9d, 0x5f, 0xb7, 0x27, 0x06, 0xcf, 0x3b, 0xdc, 0xe9, 0xea, 0x9d, 0x0e, - 0xee, 0x3a, 0xc3, 0x36, 0xf6, 0xcf, 0x41, 0x66, 0x29, 0x70, 0x6f, 0xd7, 0x3b, 0xe1, 0x21, 0xd1, - 0x3b, 0xbd, 0xec, 0x43, 0x51, 0x00, 0x96, 0x5b, 0xb6, 0xee, 0x46, 0xd0, 0xc4, 0x02, 0x34, 0x35, - 0xcb, 0xbd, 0x76, 0x35, 0x82, 0x26, 0x2e, 0x68, 0xce, 0x41, 0x66, 0x73, 0x18, 0x51, 0x22, 0x0c, - 0xf4, 0xc4, 0x95, 0x08, 0x9a, 0x89, 0x3e, 0xa0, 0x48, 0xa2, 0x9c, 0x20, 0x3a, 0x0b, 0xe9, 0xb2, - 0x6d, 0xb7, 0x22, 0x48, 0x52, 0x01, 0x9c, 0x7a, 0xe0, 0x4a, 0x72, 0x88, 0x28, 0x1d, 0xa8, 0x50, - 0x99, 0xac, 0x5b, 0x23, 0x68, 0xbc, 0x33, 0x30, 0x47, 0x3e, 0xfa, 0xf1, 0x6e, 0xde, 0x2f, 0x47, - 0x3d, 0xfa, 0x21, 0xfa, 0xf3, 0xde, 0x8e, 0x7e, 0x64, 0x03, 0x5b, 0x0f, 0x5e, 0x94, 0xa1, 0xa3, - 0x77, 0xf5, 0xb6, 0x73, 0xd4, 0x70, 0xea, 0x88, 0x93, 0x35, 0x73, 0x23, 0x34, 0x91, 0xac, 0x6c, - 0xf2, 0xde, 0x82, 0x79, 0x83, 0x56, 0x01, 0x5d, 0x0d, 0x46, 0x77, 0x32, 0xc3, 0xfd, 0x10, 0x46, - 0x2e, 0xa2, 0x3f, 0xcf, 0x43, 0x4a, 0x2c, 0xbc, 0xb8, 0x6d, 0x3e, 0x1b, 0xe5, 0x2d, 0x71, 0x12, - 0xce, 0xeb, 0xb1, 0xa0, 0xaf, 0x83, 0xb4, 0x67, 0xa9, 0xb9, 0x69, 0x52, 0x0e, 0xb3, 0xed, 0x1c, - 0xc0, 0x67, 0x42, 0x45, 0x3f, 0x3c, 0x90, 0x18, 0x1a, 0x71, 0xd8, 0x62, 0x14, 0x9c, 0xdb, 0x0b, - 0x0d, 0x3c, 0x09, 0x09, 0x7d, 0xdb, 0x30, 0xf9, 0x74, 0x7e, 0x7f, 0x04, 0x63, 0xa9, 0x5c, 0xa9, - 0x31, 0x2e, 0xfa, 0x20, 0x07, 0x25, 0x27, 0x95, 0x76, 0x0e, 0x2c, 0x63, 0xaf, 0x6b, 0x5b, 0x07, - 0x7c, 0x06, 0x8f, 0xaa, 0x74, 0x5d, 0xd0, 0x88, 0x4a, 0x7b, 0x4c, 0xa4, 0xd2, 0x3b, 0xd8, 0x9f, - 0xbd, 0xa3, 0x2b, 0xbd, 0xcc, 0x28, 0x44, 0xa5, 0x39, 0x83, 0x52, 0xe3, 0xf1, 0x54, 0xde, 0x6d, - 0xf4, 0x91, 0xaa, 0x7d, 0x8d, 0x45, 0x7a, 0xd8, 0x80, 0x4f, 0xb5, 0xf5, 0x7d, 0x3a, 0x68, 0xc8, - 0x54, 0x42, 0x32, 0x77, 0xf9, 0xc3, 0x25, 0x71, 0x35, 0xd9, 0xd6, 0xf7, 0xaf, 0xeb, 0xce, 0xcd, - 0x44, 0x2a, 0x2e, 0x27, 0x94, 0x4f, 0x12, 0xf7, 0x3b, 0xd4, 0x35, 0xe8, 0x11, 0x40, 0x84, 0x43, - 0xdf, 0xc5, 0x1a, 0x99, 0x84, 0x68, 0x27, 0x0b, 0xdc, 0x7c, 0x5b, 0xdf, 0x2f, 0xed, 0xe2, 0xb5, - 0x5e, 0x9b, 0x56, 0xc0, 0x41, 0xab, 0x20, 0x0b, 0x62, 0xa1, 0x80, 0x9e, 0xbf, 0x30, 0xf0, 0x50, - 0x36, 0x27, 0x60, 0x0e, 0xcd, 0x07, 0x89, 0x43, 0x33, 0xc5, 0xf0, 0xbc, 0x23, 0x5f, 0xa1, 0xa6, - 0xc4, 0xc3, 0x4d, 0x51, 0x5e, 0x84, 0x7c, 0x9f, 0x16, 0x20, 0x05, 0x72, 0x3c, 0x6a, 0x4d, 0x8f, - 0xd3, 0xb0, 0xb5, 0x7b, 0x5a, 0xcd, 0xb0, 0xe0, 0x34, 0x1d, 0x7d, 0xc5, 0xd4, 0x2f, 0x7e, 0x6c, - 0x5e, 0xa2, 0x5b, 0x97, 0x8f, 0x40, 0x2e, 0xa4, 0x06, 0x22, 0x70, 0x29, 0xf9, 0x81, 0x4b, 0x9f, - 0xf8, 0x55, 0xc8, 0x92, 0xa9, 0x14, 0x37, 0x39, 0xed, 0x43, 0x90, 0x67, 0x73, 0x7d, 0xbf, 0xac, - 0x99, 0x0f, 0xbf, 0x2a, 0x04, 0xae, 0x08, 0xa7, 0x3e, 0x2c, 0xf6, 0x8c, 0xa0, 0xba, 0xae, 0x3b, - 0xca, 0x0f, 0x48, 0x90, 0xef, 0xd3, 0x0d, 0xf4, 0x3c, 0xa4, 0x3b, 0x5d, 0x6c, 0x98, 0x81, 0x30, - 0xd7, 0x21, 0x22, 0x4c, 0x50, 0xf1, 0xf9, 0x1c, 0xc4, 0x4d, 0x12, 0xe7, 0x04, 0x9a, 0xb8, 0xa5, - 0x1f, 0x8c, 0xee, 0x05, 0x06, 0x21, 0x7e, 0xb5, 0x60, 0x89, 0x30, 0x29, 0xbf, 0x2a, 0x41, 0x2e, - 0xa4, 0x74, 0xa8, 0x09, 0xf7, 0x93, 0x29, 0x3a, 0x78, 0x36, 0x9d, 0xbf, 0xe6, 0x17, 0x58, 0xa3, - 0x65, 0xae, 0x9c, 0x1e, 0x28, 0xc7, 0x9f, 0x68, 0xa8, 0x73, 0x23, 0xa9, 0x73, 0x04, 0xc7, 0x3f, - 0xa2, 0xce, 0x9e, 0xfd, 0xbb, 0xc1, 0x9c, 0xf1, 0x75, 0x40, 0x9d, 0x6d, 0xb7, 0x1f, 0x3a, 0x36, - 0x2e, 0xb4, 0x4c, 0x98, 0x83, 0x80, 0x4a, 0x1d, 0xc0, 0x1f, 0xb8, 0xa8, 0x34, 0x4e, 0x23, 0xe2, - 0x87, 0xd5, 0xb0, 0x18, 0x2b, 0x48, 0xe5, 0x8d, 0x4f, 0x7c, 0xf6, 0x8c, 0xf4, 0x8e, 0xb8, 0x0e, - 0xbf, 0x5b, 0x87, 0xfb, 0x7c, 0xd2, 0x6d, 0xc3, 0xec, 0x0f, 0x68, 0xcb, 0x9e, 0x71, 0x20, 0xb9, - 0x64, 0x5a, 0x38, 0x7c, 0x3f, 0x6d, 0x64, 0xb8, 0x7b, 0xc4, 0x44, 0x34, 0x4e, 0x38, 0xfc, 0x1e, - 0xa3, 0xdd, 0xff, 0x31, 0x0d, 0x93, 0x2a, 0x7e, 0x4f, 0x0f, 0x3b, 0x2e, 0x7a, 0x02, 0x12, 0xd8, - 0xd8, 0xb3, 0x07, 0xb7, 0x9c, 0x78, 0x2b, 0x17, 0xab, 0xc6, 0x9e, 0xcd, 0x89, 0x6f, 0x1c, 0x53, - 0x29, 0x31, 0xba, 0x06, 0x13, 0x3b, 0xad, 0x1e, 0x0f, 0x84, 0x87, 0xa6, 0x29, 0xc1, 0xb5, 0x4c, - 0xb2, 0x7d, 0x36, 0x46, 0x4e, 0x0a, 0xa3, 0x3f, 0x27, 0x11, 0x1f, 0x56, 0x18, 0xfd, 0x15, 0x09, - 0xbf, 0x30, 0x42, 0x8c, 0x2a, 0x00, 0xa6, 0x65, 0xba, 0x1a, 0x8d, 0x11, 0xf3, 0x69, 0x42, 0x89, - 0x62, 0x35, 0x5d, 0x1a, 0x4f, 0xf6, 0xf9, 0xd3, 0xa6, 0x48, 0x23, 0x35, 0x7e, 0x4f, 0x0f, 0x77, - 0xc5, 0x54, 0x11, 0x51, 0xe3, 0x77, 0x91, 0xec, 0x40, 0x8d, 0x29, 0x39, 0x99, 0x5a, 0xd9, 0x53, - 0xa7, 0xee, 0x3e, 0x7f, 0xc0, 0x7b, 0x61, 0x90, 0x95, 0xbe, 0x74, 0xda, 0xd8, 0xf7, 0x99, 0x27, - 0x0d, 0x96, 0x82, 0x9e, 0xf1, 0x96, 0x70, 0x99, 0xfe, 0x35, 0x93, 0xc7, 0xcc, 0x56, 0x70, 0x1e, - 0x2f, 0x67, 0x40, 0xeb, 0x30, 0xd5, 0x32, 0x1d, 0x57, 0x73, 0x2c, 0xbd, 0xe3, 0xec, 0xd9, 0xae, - 0x43, 0x63, 0xb1, 0x99, 0x2b, 0x0f, 0x0d, 0x42, 0xac, 0x98, 0x8e, 0x5b, 0x17, 0x64, 0x3e, 0x52, - 0xae, 0x15, 0x4c, 0x27, 0x80, 0xf6, 0xce, 0x0e, 0xee, 0x7a, 0x88, 0x34, 0x68, 0x1b, 0x09, 0xb8, - 0x4e, 0xe8, 0x04, 0x67, 0x00, 0xd0, 0x0e, 0xa6, 0xa3, 0x6f, 0x80, 0x99, 0x96, 0xad, 0x37, 0x3d, - 0x3c, 0xcd, 0xd8, 0xeb, 0x59, 0xb7, 0x68, 0x88, 0x37, 0x73, 0xe5, 0x62, 0x44, 0x35, 0x6d, 0xbd, - 0x29, 0x98, 0x2b, 0x84, 0xd4, 0x47, 0x9e, 0x6e, 0xf5, 0xe7, 0x21, 0x0d, 0x66, 0xf5, 0x4e, 0xa7, - 0x75, 0xd0, 0x0f, 0x9f, 0xa7, 0xf0, 0x8f, 0x0c, 0xc2, 0x97, 0x08, 0xf5, 0x10, 0x7c, 0xa4, 0x0f, - 0x64, 0xa2, 0x4d, 0x90, 0x3b, 0x5d, 0x4c, 0xef, 0xad, 0x76, 0xf8, 0x22, 0x85, 0xbe, 0x11, 0x98, - 0xb9, 0x72, 0x61, 0x10, 0x7c, 0x83, 0x51, 0x8a, 0xd5, 0x8c, 0x8f, 0x9c, 0xef, 0x84, 0x73, 0x18, - 0xac, 0x6d, 0x60, 0xfa, 0x86, 0x29, 0x87, 0x9d, 0x1e, 0x0e, 0x4b, 0x29, 0x23, 0x61, 0x43, 0x39, - 0x68, 0x19, 0x32, 0x2c, 0xaa, 0xa5, 0x11, 0x13, 0x49, 0xdf, 0x16, 0xcc, 0x5c, 0x39, 0x17, 0x31, - 0x5c, 0x29, 0xd1, 0x96, 0xed, 0x62, 0x1f, 0x0c, 0xb0, 0x97, 0x88, 0xb6, 0xe1, 0x38, 0x7d, 0x67, - 0xf1, 0x40, 0x0b, 0xdb, 0xe3, 0xc2, 0x0c, 0x45, 0x7c, 0x74, 0x10, 0x91, 0xfe, 0xc8, 0xc0, 0xc1, - 0x56, 0xd0, 0x30, 0xfb, 0xd0, 0x33, 0xb7, 0x07, 0x73, 0x89, 0xa6, 0xed, 0x98, 0x96, 0xde, 0x32, - 0x5f, 0xc7, 0xcc, 0x79, 0xa1, 0x4f, 0x0c, 0x47, 0x6a, 0xda, 0x32, 0xa7, 0xa3, 0xce, 0x4c, 0x40, - 0xd3, 0x76, 0x82, 0xe9, 0xe5, 0x49, 0xbe, 0xe4, 0xf0, 0xde, 0xcc, 0x9c, 0x94, 0x53, 0xec, 0x9d, - 0xcc, 0x9b, 0x89, 0x14, 0xc8, 0x19, 0xe5, 0x3c, 0x64, 0x02, 0x76, 0x0a, 0x15, 0x60, 0x92, 0x4f, - 0xaa, 0xe2, 0x00, 0x3f, 0xff, 0x54, 0xa6, 0x20, 0x1b, 0x34, 0x4d, 0xca, 0x07, 0x24, 0xc8, 0x04, - 0x8c, 0x0e, 0xe1, 0x0c, 0x6e, 0x74, 0xa5, 0x7d, 0x3f, 0xf5, 0x9c, 0xf0, 0x2a, 0x44, 0x3e, 0xdb, - 0x6c, 0xcd, 0xd2, 0x44, 0xee, 0xd4, 0xa0, 0x79, 0xc8, 0x74, 0xae, 0x74, 0x3c, 0x92, 0x38, 0x25, - 0x81, 0xce, 0x95, 0x8e, 0x20, 0x38, 0x0b, 0x59, 0xd2, 0x74, 0x2d, 0xe8, 0x2e, 0xa7, 0xd5, 0x0c, - 0x49, 0xe3, 0x24, 0xca, 0x6f, 0xc6, 0x40, 0xee, 0x37, 0x66, 0xde, 0x06, 0x98, 0x74, 0xe4, 0x0d, - 0xb0, 0x53, 0xfd, 0x5b, 0x6f, 0xfe, 0x6e, 0xdb, 0x2a, 0xc8, 0xfe, 0x9e, 0x11, 0x9b, 0x7b, 0x0e, - 0xf1, 0xff, 0xfb, 0xd6, 0x2a, 0x6a, 0xde, 0xe8, 0x5b, 0xbc, 0x5c, 0x0f, 0x9d, 0x17, 0x49, 0x78, - 0x47, 0x5c, 0xfb, 0xf5, 0x49, 0xd0, 0x6c, 0x76, 0x9a, 0xba, 0x8b, 0x45, 0xc8, 0x3d, 0x70, 0x74, - 0xe4, 0x21, 0xc8, 0xeb, 0x9d, 0x8e, 0xe6, 0xb8, 0xba, 0x8b, 0xb9, 0xa3, 0xc7, 0x02, 0x99, 0x39, - 0xbd, 0xd3, 0xa1, 0xbf, 0x73, 0xc1, 0x1c, 0xbd, 0x07, 0x61, 0x8a, 0x58, 0x78, 0x53, 0x6f, 0x09, - 0x2f, 0x22, 0xc9, 0xfc, 0x41, 0x9e, 0xca, 0x3d, 0x91, 0x26, 0x64, 0x83, 0xc6, 0xdd, 0x0b, 0xcd, - 0x48, 0x81, 0xd0, 0x0c, 0xe2, 0x0f, 0x2f, 0x31, 0x09, 0x89, 0xc7, 0xaa, 0xa2, 0x37, 0x23, 0x67, - 0x69, 0x18, 0xe7, 0x36, 0x8b, 0xbd, 0xa6, 0x54, 0xf6, 0xa1, 0xbc, 0x02, 0x53, 0xe1, 0x79, 0x00, - 0x4d, 0x41, 0xcc, 0xdd, 0xe7, 0xa5, 0xc4, 0xdc, 0x7d, 0x74, 0x39, 0xf0, 0x0b, 0x21, 0x53, 0x51, - 0xb3, 0x1f, 0xe7, 0xf7, 0x43, 0xa7, 0x37, 0x13, 0xa9, 0x98, 0x1c, 0x57, 0xf2, 0x90, 0x0b, 0xcd, - 0x12, 0xca, 0x09, 0x98, 0x8d, 0xb2, 0xf9, 0x8a, 0x09, 0xb3, 0x51, 0xa6, 0x1b, 0x5d, 0x83, 0x94, - 0x67, 0xf4, 0x07, 0xa2, 0x6d, 0xa2, 0x74, 0x8f, 0xc9, 0xa3, 0x0d, 0xed, 0x16, 0xc6, 0x42, 0xbb, - 0x85, 0xca, 0x37, 0x43, 0x61, 0x98, 0x3d, 0xef, 0xdb, 0x3e, 0x48, 0x78, 0x82, 0x3b, 0x01, 0x49, - 0xfe, 0xda, 0x70, 0x8c, 0x86, 0x29, 0xf8, 0x17, 0x11, 0x28, 0xb3, 0xed, 0x71, 0x16, 0xbd, 0xa0, - 0x1f, 0x8a, 0x06, 0xa7, 0x86, 0x9a, 0xf4, 0xe1, 0xbb, 0xed, 0x0c, 0x88, 0xef, 0xb6, 0xd3, 0x0f, - 0xfa, 0x2b, 0x54, 0xd8, 0x12, 0x41, 0xc0, 0xb4, 0xca, 0xbf, 0x94, 0x0f, 0xc5, 0xe1, 0x44, 0xb4, - 0x5d, 0x47, 0x0b, 0x90, 0x25, 0x8b, 0x07, 0x37, 0xbc, 0xce, 0x80, 0xb6, 0xbe, 0xdf, 0xe0, 0x8b, - 0x0c, 0xbe, 0x53, 0x19, 0xf3, 0x76, 0x2a, 0xd1, 0x16, 0x4c, 0xb7, 0x6c, 0x43, 0x6f, 0x69, 0x81, - 0x9d, 0x62, 0x3e, 0x9c, 0x1e, 0x18, 0x66, 0xa7, 0xc5, 0x5e, 0x04, 0x31, 0x41, 0x7c, 0x20, 0xe4, - 0x29, 0xc8, 0x8a, 0xb7, 0xab, 0x8c, 0xaa, 0x90, 0x69, 0x9b, 0xce, 0x36, 0xde, 0xd3, 0x6f, 0x9b, - 0x76, 0x97, 0x8f, 0xab, 0x08, 0xed, 0x59, 0xf5, 0x89, 0xc4, 0x16, 0x76, 0x80, 0x2f, 0xd0, 0x29, - 0x13, 0x91, 0x5b, 0xeb, 0xc9, 0x23, 0x5b, 0x96, 0x61, 0x9b, 0xd4, 0x93, 0x43, 0x37, 0xa9, 0xa3, - 0x76, 0x84, 0x53, 0xd1, 0x3b, 0xc2, 0x6f, 0xd0, 0xce, 0x89, 0x9a, 0x1d, 0x07, 0x37, 0x89, 0x51, - 0x03, 0x66, 0x39, 0x7f, 0x33, 0x24, 0xfd, 0x81, 0x73, 0x67, 0x61, 0xa7, 0x2b, 0x20, 0x75, 0x24, - 0xf8, 0x87, 0x0b, 0x3e, 0x7e, 0x8f, 0x82, 0x17, 0x47, 0x35, 0x12, 0x81, 0xa3, 0x1a, 0xff, 0x8f, - 0x75, 0xc6, 0xfb, 0xe2, 0x62, 0xf3, 0x2c, 0xe0, 0x58, 0x44, 0x9e, 0x41, 0x19, 0xb6, 0xd7, 0x23, - 0x1a, 0x16, 0x3f, 0x72, 0xc3, 0x78, 0x6f, 0x27, 0x46, 0xf7, 0xf6, 0xc4, 0xdb, 0xd9, 0xdb, 0xc9, - 0x7b, 0xec, 0xed, 0x77, 0xb4, 0x1f, 0x3e, 0x22, 0xc1, 0xdc, 0x70, 0x77, 0x2c, 0xb2, 0x43, 0x8e, - 0xb4, 0x3b, 0x39, 0x6c, 0xc6, 0x7b, 0x10, 0xa6, 0xfa, 0xbc, 0x45, 0xa6, 0xcc, 0xb9, 0xd0, 0x72, - 0x5d, 0xf9, 0xf6, 0x38, 0xcc, 0x46, 0x39, 0x74, 0x11, 0x23, 0x56, 0x85, 0x99, 0x26, 0x36, 0xcc, - 0xe6, 0x3d, 0x0f, 0xd8, 0x69, 0xce, 0xfe, 0xff, 0xc7, 0x6b, 0x84, 0x9e, 0xfc, 0x38, 0x40, 0x4a, - 0xc5, 0x4e, 0x87, 0x38, 0x68, 0xec, 0xd7, 0x0e, 0x0d, 0xdc, 0x71, 0xfd, 0xb0, 0x56, 0xe4, 0xba, - 0x81, 0x93, 0x08, 0x3e, 0xb2, 0x7e, 0xf6, 0xf8, 0xd0, 0x55, 0x1e, 0x26, 0x18, 0xba, 0xe0, 0x67, - 0xee, 0xb7, 0xc7, 0xca, 0xe2, 0x04, 0x4f, 0x89, 0x38, 0x41, 0x7c, 0xd8, 0xea, 0x97, 0x3b, 0xe3, - 0x1e, 0x1f, 0x0f, 0x14, 0x5c, 0xe5, 0x81, 0x82, 0xc4, 0xb0, 0xe2, 0x98, 0xcf, 0xee, 0x17, 0x67, - 0xb2, 0x87, 0x4c, 0x83, 0x91, 0x82, 0xe4, 0xb0, 0xa6, 0x06, 0x9c, 0x6b, 0xbf, 0xa9, 0x7e, 0xa8, - 0xe0, 0x29, 0x11, 0x2a, 0x98, 0x1c, 0x56, 0x69, 0xee, 0x4d, 0xfa, 0x95, 0x66, 0xb1, 0x82, 0x17, - 0x02, 0xb1, 0x82, 0x74, 0x7f, 0x18, 0x7e, 0x20, 0x56, 0xe0, 0x71, 0x7b, 0xc1, 0x82, 0xa2, 0x17, - 0x2c, 0xc8, 0x0e, 0x8d, 0x34, 0x70, 0x37, 0xd0, 0x63, 0x16, 0xd1, 0x82, 0x8d, 0x81, 0x68, 0x01, - 0x5b, 0xdc, 0x9f, 0x1f, 0x19, 0x2d, 0xf0, 0xa0, 0xfa, 0xc2, 0x05, 0x1b, 0x03, 0xe1, 0x82, 0xa9, - 0x61, 0x88, 0x7d, 0x3e, 0xa7, 0x8f, 0x18, 0x8e, 0x17, 0x7c, 0x63, 0x74, 0xbc, 0x60, 0xe8, 0x82, - 0x3e, 0xc2, 0xbf, 0xf4, 0xa0, 0x23, 0x02, 0x06, 0xdf, 0x3c, 0x24, 0x60, 0x20, 0x0f, 0x5b, 0xd8, - 0x46, 0x79, 0x97, 0x5e, 0x01, 0x51, 0x11, 0x83, 0xad, 0x88, 0x88, 0x01, 0x5b, 0xda, 0x3f, 0x3c, - 0x46, 0xc4, 0xc0, 0x83, 0x1e, 0x08, 0x19, 0x6c, 0x45, 0x84, 0x0c, 0xd0, 0x70, 0xdc, 0x3e, 0xa7, - 0x28, 0x88, 0x1b, 0x8e, 0x19, 0x5c, 0x0f, 0xc7, 0x0c, 0x66, 0x0e, 0xf7, 0x45, 0xd9, 0xd4, 0xee, - 0xa1, 0x05, 0x83, 0x06, 0xc6, 0xb0, 0xa0, 0x01, 0x5b, 0xd7, 0x3f, 0x36, 0x66, 0xd0, 0xc0, 0xc3, - 0x8e, 0x8c, 0x1a, 0x6c, 0x0c, 0x44, 0x0d, 0x8e, 0x0f, 0x53, 0xb8, 0xbe, 0x49, 0xc6, 0x57, 0xb8, - 0xa1, 0x61, 0x03, 0xf6, 0x23, 0x1b, 0xec, 0xe7, 0x35, 0x40, 0xce, 0xdc, 0x4c, 0xa4, 0x32, 0x72, - 0x56, 0x79, 0x98, 0xb8, 0x35, 0x7d, 0x76, 0x8f, 0x2c, 0x22, 0x70, 0xb7, 0x6b, 0x77, 0xc5, 0x1e, - 0x28, 0xfd, 0x50, 0x2e, 0x40, 0x36, 0x68, 0xe2, 0x0e, 0x09, 0x31, 0xe4, 0x21, 0x17, 0xb2, 0x6a, - 0xca, 0x2f, 0x4a, 0x90, 0x0d, 0xda, 0xab, 0xd0, 0x02, 0x34, 0xcd, 0x17, 0xa0, 0x81, 0xc0, 0x43, - 0x2c, 0x1c, 0x78, 0x98, 0x87, 0x0c, 0x59, 0x84, 0xf5, 0xc5, 0x14, 0xf4, 0x8e, 0x17, 0x53, 0x10, - 0x07, 0x37, 0x59, 0x78, 0x82, 0xcf, 0x53, 0xec, 0xd4, 0x42, 0xde, 0x3b, 0xc4, 0xca, 0xc3, 0xfc, - 0x8f, 0xc1, 0x4c, 0x80, 0xd6, 0x5b, 0xdc, 0xb1, 0xe5, 0xb5, 0xec, 0x51, 0x97, 0xf8, 0x2a, 0xef, - 0x57, 0x25, 0x98, 0x1e, 0x30, 0x97, 0x91, 0x71, 0x03, 0xe9, 0xed, 0x8a, 0x1b, 0xc4, 0xee, 0x3d, - 0x6e, 0x10, 0x5c, 0xae, 0xc6, 0xc3, 0xcb, 0xd5, 0xbf, 0x94, 0x20, 0x17, 0x32, 0xdb, 0xa4, 0x13, - 0x0c, 0xbb, 0x29, 0x76, 0xcc, 0xe9, 0xdf, 0xc4, 0x4f, 0x69, 0xd9, 0xbb, 0x7c, 0x99, 0x48, 0xfe, - 0x24, 0x54, 0xde, 0x44, 0x94, 0xe6, 0xd3, 0x8c, 0xb7, 0xf6, 0x9c, 0x08, 0xde, 0x29, 0xe3, 0xf7, - 0xac, 0x92, 0xfe, 0x3d, 0x2b, 0x6f, 0xa3, 0x7c, 0x32, 0xb0, 0x51, 0x8e, 0x9e, 0x81, 0x34, 0xdd, - 0x05, 0xd0, 0xec, 0x8e, 0xff, 0xc3, 0xcc, 0xc3, 0xef, 0x58, 0x39, 0xf4, 0x92, 0x00, 0xbb, 0x98, - 0xe5, 0x7b, 0x21, 0xe9, 0x90, 0x17, 0x72, 0x1f, 0xa4, 0x49, 0xf5, 0xd9, 0x8f, 0x1b, 0x01, 0x7f, - 0x6a, 0x44, 0x24, 0x28, 0x3f, 0x15, 0x83, 0x7c, 0xdf, 0xac, 0x13, 0xd9, 0xf8, 0xa8, 0x13, 0x2b, - 0xe3, 0x09, 0xe4, 0x0c, 0xc0, 0xae, 0xee, 0x68, 0x77, 0x74, 0xcb, 0xe5, 0xbf, 0x61, 0x1a, 0x57, - 0x03, 0x29, 0x68, 0x0e, 0x52, 0xe4, 0xab, 0xe7, 0xf0, 0x5f, 0x31, 0x8d, 0xab, 0xde, 0x37, 0xaa, - 0x41, 0x12, 0xdf, 0xa6, 0xcf, 0x71, 0xb3, 0x47, 0xed, 0x4f, 0x46, 0x98, 0x27, 0x92, 0x5f, 0x2e, - 0x90, 0xee, 0xfe, 0xa3, 0x37, 0xe7, 0x65, 0x46, 0xfe, 0xa8, 0x77, 0x81, 0x55, 0xe5, 0x00, 0x61, - 0x31, 0xa4, 0xfa, 0xc4, 0x40, 0xc3, 0x85, 0x59, 0xb1, 0xf6, 0x27, 0x42, 0x65, 0x37, 0x71, 0xd4, - 0x5c, 0x1b, 0xb7, 0x3b, 0xb6, 0xdd, 0xd2, 0xd8, 0x38, 0x2f, 0xc1, 0x54, 0x78, 0x92, 0x65, 0xbf, - 0x3c, 0xe8, 0xea, 0xa6, 0xa5, 0x85, 0x7c, 0xe3, 0x2c, 0x4b, 0x64, 0xe3, 0xea, 0x66, 0x22, 0x25, - 0xc9, 0x31, 0x1e, 0xae, 0x79, 0x17, 0x1c, 0x8f, 0x9c, 0x63, 0xd1, 0xd3, 0x90, 0xf6, 0xe7, 0x67, - 0x76, 0x9f, 0xea, 0xb0, 0x38, 0x8c, 0x4f, 0xac, 0x6c, 0xc1, 0xf1, 0xc8, 0x49, 0x16, 0x3d, 0x0f, - 0x49, 0x76, 0x5e, 0x9b, 0x9f, 0xc9, 0x7b, 0x70, 0xf4, 0xec, 0xdc, 0x6b, 0xb9, 0x2a, 0x67, 0x52, - 0x2e, 0xc3, 0xa9, 0xa1, 0xb3, 0xac, 0x1f, 0x4d, 0x91, 0x02, 0xd1, 0x14, 0xe5, 0x67, 0x24, 0x98, - 0x1b, 0x3e, 0x73, 0xa2, 0x72, 0x5f, 0x85, 0x2e, 0x8e, 0x39, 0xef, 0x06, 0x6a, 0x45, 0x96, 0x1b, - 0x5d, 0xbc, 0x83, 0x5d, 0x63, 0x8f, 0x4d, 0xe1, 0xcc, 0x28, 0xe4, 0xd4, 0x1c, 0x4f, 0xa5, 0x3c, - 0x0e, 0x23, 0x7b, 0x0d, 0x1b, 0xae, 0xc6, 0x3a, 0xd5, 0xe1, 0x3f, 0x35, 0x9f, 0x63, 0xa9, 0x75, - 0x96, 0xa8, 0x3c, 0x02, 0x27, 0x87, 0xcc, 0xc5, 0x11, 0xc7, 0xcd, 0x5f, 0x25, 0xc4, 0x91, 0x13, - 0x2c, 0x7a, 0x11, 0x92, 0x8e, 0xab, 0xbb, 0x3d, 0x87, 0xb7, 0xec, 0xfc, 0xc8, 0xb9, 0xb9, 0x4e, - 0xc9, 0x55, 0xce, 0xa6, 0x3c, 0x0b, 0x68, 0x70, 0xa6, 0x8d, 0x58, 0x5b, 0x49, 0x51, 0x6b, 0xab, - 0x6d, 0x38, 0x7d, 0xc8, 0x9c, 0x8a, 0x2a, 0x7d, 0x95, 0x7b, 0x64, 0xac, 0x29, 0xb9, 0xaf, 0x82, - 0x7f, 0x12, 0x83, 0xe3, 0x91, 0x53, 0x6b, 0x60, 0x94, 0x4a, 0x6f, 0x75, 0x94, 0x3e, 0x0f, 0xe0, - 0xee, 0x8b, 0x4b, 0x06, 0xdc, 0xda, 0x47, 0xad, 0x27, 0xf6, 0xb1, 0x41, 0x0d, 0x16, 0x51, 0x8c, - 0xb4, 0xcb, 0xff, 0x22, 0x8b, 0xff, 0xc0, 0x7a, 0xb6, 0x47, 0x67, 0x02, 0x87, 0x2f, 0xf5, 0xc6, - 0x9e, 0x33, 0xfc, 0x85, 0x2f, 0x4b, 0x76, 0xd0, 0xab, 0x70, 0xb2, 0x6f, 0x46, 0xf3, 0xb0, 0x13, - 0x63, 0x4f, 0x6c, 0xc7, 0xc3, 0x13, 0x9b, 0xc0, 0x0e, 0xce, 0x4a, 0x13, 0xe1, 0x59, 0xe9, 0x55, - 0x00, 0x7f, 0x61, 0xeb, 0x9f, 0x87, 0x95, 0x82, 0xe7, 0x61, 0xaf, 0xc1, 0x04, 0xd1, 0x04, 0x21, - 0xaa, 0x08, 0x83, 0x41, 0xba, 0x34, 0xb0, 0x32, 0x66, 0xe4, 0xca, 0x6b, 0x42, 0xdb, 0x82, 0x31, - 0xc6, 0x21, 0x65, 0xbc, 0x10, 0x2e, 0x43, 0x19, 0x1e, 0xae, 0x8c, 0x2e, 0xeb, 0x6f, 0xc1, 0x04, - 0xed, 0xfe, 0xc8, 0x0b, 0xc8, 0xdf, 0x04, 0xa0, 0xbb, 0x6e, 0xd7, 0xdc, 0xee, 0xf9, 0x25, 0x2c, - 0x0c, 0xd1, 0x9f, 0x92, 0x20, 0x2c, 0xdf, 0xc7, 0x15, 0x69, 0xd6, 0xe7, 0x0d, 0x28, 0x53, 0x00, - 0x51, 0x59, 0x83, 0xa9, 0x30, 0x6f, 0xf4, 0x8d, 0x6a, 0xff, 0xdd, 0x26, 0x71, 0xae, 0xcd, 0x9f, - 0xc8, 0xf9, 0x5b, 0x6a, 0xf4, 0x43, 0xf9, 0x96, 0x18, 0x64, 0x83, 0xda, 0xf7, 0x37, 0x70, 0xb2, - 0x54, 0xbe, 0x5d, 0x82, 0x94, 0xd7, 0xfe, 0x43, 0x6e, 0x03, 0xf8, 0x77, 0xeb, 0xbd, 0x18, 0x3c, - 0xdb, 0xf5, 0x88, 0x7b, 0xbb, 0x1e, 0xcf, 0x79, 0x13, 0xc2, 0xd0, 0xc5, 0x7c, 0x50, 0xda, 0xe2, - 0x1c, 0x2e, 0x9f, 0xa0, 0x9e, 0x1d, 0xef, 0x72, 0xef, 0x2c, 0x4c, 0x04, 0xef, 0xe5, 0xb2, 0x0f, - 0x05, 0x07, 0x8e, 0x2b, 0xb1, 0xd1, 0x18, 0xbc, 0x05, 0x2c, 0x1d, 0xfd, 0x16, 0xb0, 0x57, 0x4c, - 0x2c, 0x58, 0xcc, 0x3f, 0x90, 0x20, 0x25, 0xc6, 0x05, 0x7a, 0x31, 0x78, 0x98, 0x4e, 0x9c, 0xcc, - 0x19, 0x6e, 0x97, 0x78, 0x01, 0x81, 0xb3, 0x74, 0x03, 0x57, 0x12, 0xe2, 0x47, 0xbe, 0x92, 0xc0, - 0xfd, 0x90, 0x2f, 0x4b, 0x20, 0xf7, 0x8f, 0xdb, 0xb7, 0x5e, 0xbf, 0xc1, 0xf9, 0x2a, 0x1e, 0x31, - 0x5f, 0x0d, 0xbb, 0x68, 0x90, 0x18, 0x76, 0xd1, 0x60, 0xb0, 0xdd, 0x13, 0xf7, 0xda, 0xee, 0xf7, - 0xc5, 0x20, 0x13, 0x88, 0xf1, 0xa1, 0x27, 0x43, 0xb7, 0x16, 0xce, 0x1e, 0x1a, 0x10, 0x0c, 0x5c, - 0x5b, 0x08, 0x49, 0x2a, 0x76, 0x0f, 0x92, 0x7a, 0xfb, 0x2f, 0x33, 0x46, 0xdf, 0x8c, 0x9f, 0x18, - 0x72, 0x33, 0xfe, 0xef, 0x48, 0x90, 0xf2, 0x82, 0x2f, 0x47, 0xdd, 0x93, 0x3b, 0x01, 0x49, 0xee, - 0x7b, 0xb1, 0x4d, 0x39, 0xfe, 0x15, 0x19, 0x1d, 0x9d, 0x83, 0x94, 0xf8, 0x95, 0x55, 0x3e, 0xc3, - 0x79, 0xdf, 0x17, 0xb7, 0x21, 0x13, 0xd8, 0xd6, 0x44, 0xa7, 0xe0, 0x78, 0xe5, 0x46, 0xb5, 0xf2, - 0x92, 0xd6, 0x78, 0xb9, 0xff, 0xb7, 0xf5, 0x06, 0xb2, 0xd4, 0x2a, 0xfd, 0x96, 0x25, 0x74, 0x12, - 0x66, 0xc2, 0x59, 0x2c, 0x23, 0x36, 0x97, 0x78, 0xff, 0x8f, 0x9d, 0x39, 0x76, 0xf1, 0xcb, 0x12, - 0xcc, 0x44, 0x78, 0xb9, 0xe8, 0x2c, 0xdc, 0xbf, 0xbe, 0xbc, 0x5c, 0x55, 0xb5, 0xfa, 0x5a, 0x69, - 0xa3, 0x7e, 0x63, 0xbd, 0xa1, 0xa9, 0xd5, 0xfa, 0xe6, 0x4a, 0x23, 0x50, 0xe8, 0x02, 0xdc, 0x17, - 0x4d, 0x52, 0xaa, 0x54, 0xaa, 0x1b, 0x0d, 0xf6, 0xe3, 0x7e, 0x43, 0x28, 0xca, 0xeb, 0x6a, 0x43, - 0x8e, 0x0d, 0x87, 0x50, 0xab, 0x37, 0xab, 0x95, 0x86, 0x1c, 0x47, 0xe7, 0xe1, 0xdc, 0x61, 0x14, - 0xda, 0xf2, 0xba, 0xba, 0x5a, 0x6a, 0xc8, 0x89, 0x91, 0x84, 0xf5, 0xea, 0xda, 0x52, 0x55, 0x95, - 0x27, 0x78, 0xbb, 0x3f, 0x16, 0x83, 0xc2, 0x30, 0x67, 0x9a, 0x60, 0x95, 0x36, 0x36, 0x56, 0x5e, - 0xf1, 0xb1, 0x2a, 0x37, 0x36, 0xd7, 0x5e, 0x1a, 0x14, 0xc1, 0x43, 0xa0, 0x1c, 0x46, 0xe8, 0x09, - 0xe2, 0x41, 0x38, 0x7b, 0x28, 0x1d, 0x17, 0xc7, 0x08, 0x32, 0xb5, 0xda, 0x50, 0x5f, 0x91, 0xe3, - 0x68, 0x11, 0x2e, 0x8e, 0x24, 0xf3, 0xf2, 0xe4, 0x04, 0xba, 0x04, 0x8f, 0x1c, 0x4e, 0xcf, 0x04, - 0x24, 0x18, 0x84, 0x88, 0xde, 0x90, 0xe0, 0x78, 0xa4, 0x57, 0x8e, 0xce, 0xc1, 0xfc, 0x86, 0xba, - 0x5e, 0xa9, 0xd6, 0xeb, 0xde, 0x9d, 0x05, 0xad, 0xde, 0x28, 0x35, 0x36, 0xeb, 0x01, 0xd9, 0x28, - 0x70, 0x66, 0x18, 0x91, 0x27, 0x97, 0x43, 0x68, 0xb8, 0x06, 0x08, 0x3d, 0xbd, 0x2b, 0xc1, 0xa9, - 0xa1, 0x5e, 0x38, 0xba, 0x00, 0x0f, 0x6c, 0x55, 0xd5, 0xda, 0xf2, 0x2b, 0xda, 0xd6, 0x7a, 0x23, - 0xf8, 0x2b, 0x92, 0x03, 0xb5, 0x3a, 0x0f, 0xe7, 0x0e, 0xa5, 0xf4, 0xaa, 0x36, 0x8a, 0xb0, 0xaf, - 0x7e, 0xdf, 0x26, 0x41, 0xbe, 0xcf, 0x16, 0xa2, 0xfb, 0xa0, 0xb0, 0x5a, 0xab, 0x97, 0xab, 0x37, - 0x4a, 0x5b, 0xb5, 0x75, 0xb5, 0x7f, 0xcc, 0x9e, 0x83, 0xf9, 0x81, 0xdc, 0xa5, 0xcd, 0x8d, 0x95, - 0x5a, 0xa5, 0xd4, 0xa8, 0x6a, 0xec, 0xa2, 0x09, 0x69, 0xd8, 0x00, 0xd1, 0x4a, 0xed, 0xfa, 0x8d, - 0x86, 0x56, 0x59, 0xa9, 0x55, 0xd7, 0x1a, 0x5a, 0xa9, 0xd1, 0x28, 0xf9, 0xc3, 0xb9, 0xfc, 0xd2, - 0xd0, 0x03, 0x9e, 0x97, 0xc7, 0x3f, 0xe0, 0xc9, 0x8f, 0x70, 0x7a, 0xe7, 0x3b, 0xff, 0xf3, 0x13, - 0xf0, 0x00, 0x7f, 0x98, 0xc8, 0x71, 0xf5, 0x5b, 0xa6, 0xb5, 0xeb, 0xbd, 0x10, 0xc5, 0xbf, 0xf9, - 0x39, 0xcf, 0x13, 0xfc, 0x15, 0x24, 0x91, 0x3a, 0xe2, 0x9d, 0xa8, 0xa1, 0xcf, 0x8b, 0x8e, 0xbc, - 0x1f, 0x30, 0xea, 0x98, 0xe6, 0x61, 0x6f, 0x50, 0x8d, 0x78, 0xe9, 0x2a, 0xe2, 0x8d, 0xaa, 0xb9, - 0xc3, 0xdf, 0x6b, 0x98, 0x3b, 0xf4, 0xf0, 0xab, 0xf2, 0x41, 0x09, 0xa6, 0x6e, 0x98, 0x8e, 0x6b, - 0x77, 0x4d, 0x43, 0x6f, 0x51, 0x47, 0xe2, 0xb9, 0xb1, 0x2f, 0xb4, 0x95, 0xd3, 0x64, 0x1a, 0xe3, - 0x2f, 0x59, 0xed, 0x89, 0x3b, 0x65, 0xc9, 0xdb, 0x7a, 0x8b, 0x5d, 0x26, 0x0b, 0x3e, 0x85, 0xd7, - 0x2f, 0xf6, 0xc0, 0xfc, 0x1a, 0x44, 0x61, 0xbc, 0xc5, 0x58, 0x41, 0x52, 0x7e, 0x20, 0x06, 0x79, - 0xba, 0xc0, 0x71, 0xe8, 0x82, 0x98, 0x2e, 0xb9, 0x6e, 0x42, 0xa2, 0xab, 0xbb, 0x7c, 0x19, 0x52, - 0xbe, 0x76, 0xe4, 0xe7, 0xaf, 0x58, 0x29, 0x14, 0x03, 0xbd, 0x0b, 0x52, 0x6d, 0x7d, 0x5f, 0xa3, - 0x78, 0xb1, 0xb7, 0x84, 0x37, 0xd9, 0xd6, 0xf7, 0x49, 0xfd, 0xd0, 0x37, 0x41, 0x9e, 0x40, 0x1a, - 0x7b, 0xba, 0xb5, 0x8b, 0x19, 0x72, 0xfc, 0x2d, 0x21, 0xe7, 0xda, 0xfa, 0x7e, 0x85, 0xa2, 0x11, - 0x7c, 0xfe, 0x4c, 0xd8, 0xaf, 0x48, 0x7c, 0x75, 0x49, 0x05, 0x83, 0x74, 0x90, 0x0d, 0xef, 0x8b, - 0x16, 0x2a, 0x82, 0xb6, 0xe7, 0x87, 0xc9, 0xbe, 0x4f, 0xac, 0xe5, 0x1c, 0xa9, 0xde, 0x67, 0xde, - 0x9c, 0x97, 0x58, 0xa9, 0x79, 0x63, 0x40, 0xec, 0x19, 0xb6, 0x6a, 0xd6, 0xa8, 0x7f, 0x13, 0x1b, - 0xe9, 0xdf, 0xe4, 0x84, 0x7f, 0xc3, 0x00, 0x81, 0x71, 0x93, 0x7c, 0xde, 0x86, 0x4f, 0x48, 0x90, - 0x59, 0x0a, 0x3c, 0xdd, 0x59, 0x80, 0xc9, 0xb6, 0x6d, 0x99, 0xb7, 0x70, 0xd7, 0x8b, 0xba, 0xb3, - 0x4f, 0xe2, 0x83, 0xb0, 0x5f, 0x80, 0x74, 0x0f, 0xc4, 0x03, 0x2a, 0xe2, 0x9b, 0x70, 0xdd, 0xc1, - 0xdb, 0x8e, 0x29, 0xe4, 0xac, 0x8a, 0x4f, 0xf4, 0x30, 0xc8, 0x0e, 0x36, 0x7a, 0x5d, 0xd3, 0x3d, - 0xd0, 0x0c, 0xdb, 0x72, 0x75, 0xc3, 0xe5, 0x8b, 0xb5, 0xbc, 0x48, 0xaf, 0xb0, 0x64, 0x02, 0xd2, - 0xc4, 0xae, 0x6e, 0xb6, 0xd8, 0x61, 0xb4, 0xb4, 0x2a, 0x3e, 0x79, 0x55, 0xef, 0x4e, 0x06, 0x97, - 0x2a, 0x15, 0x90, 0xed, 0x0e, 0xee, 0x86, 0x76, 0xdd, 0x99, 0x36, 0x16, 0x7e, 0xeb, 0xd3, 0x8f, - 0xcd, 0x72, 0x81, 0xf3, 0xfd, 0x5a, 0x76, 0x03, 0x4b, 0xcd, 0x0b, 0x0e, 0xb1, 0x1d, 0xff, 0x4a, - 0x28, 0xce, 0xde, 0xdb, 0xf6, 0xdf, 0x2e, 0x9a, 0x1d, 0x10, 0x6a, 0xc9, 0x3a, 0x28, 0x17, 0x7e, - 0xc3, 0x87, 0xe6, 0x8b, 0x99, 0x0d, 0xba, 0x70, 0x09, 0xc6, 0xdc, 0x29, 0x0c, 0x71, 0xef, 0x5e, - 0xd3, 0xcd, 0x96, 0xf8, 0xb1, 0x5c, 0x95, 0x7f, 0xa1, 0xa2, 0x17, 0x47, 0x4a, 0x50, 0x6f, 0x59, - 0x19, 0xa6, 0x1b, 0x65, 0xdb, 0x6a, 0x86, 0xc3, 0x47, 0xa8, 0x02, 0x49, 0xd7, 0xbe, 0x85, 0x2d, - 0x2e, 0xa0, 0xf2, 0x23, 0x47, 0x78, 0xe7, 0x4e, 0xe5, 0xac, 0xe8, 0x1b, 0x40, 0x6e, 0xe2, 0x16, - 0xde, 0x65, 0x97, 0x4d, 0xf7, 0xf4, 0x2e, 0x66, 0xaf, 0x1e, 0xdc, 0xd3, 0x2b, 0x76, 0x79, 0x0f, - 0xaa, 0x4e, 0x91, 0xd0, 0x46, 0xf8, 0x71, 0xd8, 0x49, 0x6f, 0x8b, 0x38, 0xb2, 0x8d, 0x01, 0xcd, - 0x0b, 0x5a, 0x9f, 0xd0, 0x63, 0xb2, 0x0f, 0x83, 0xdc, 0xb3, 0xb6, 0x6d, 0x8b, 0xfe, 0xc6, 0x24, - 0xf7, 0xb0, 0x53, 0x6c, 0xef, 0xc5, 0x4b, 0xe7, 0x7b, 0x2f, 0x1b, 0x30, 0xe5, 0x93, 0xd2, 0x11, - 0x92, 0x3e, 0xea, 0x08, 0xc9, 0x79, 0x00, 0x84, 0x04, 0xad, 0x02, 0xf8, 0x63, 0x90, 0x46, 0xfe, - 0x33, 0xc3, 0x7b, 0xcc, 0x1f, 0xcd, 0xc1, 0xc6, 0x04, 0x00, 0x90, 0x05, 0x33, 0x6d, 0xd3, 0xd2, - 0x1c, 0xdc, 0xda, 0xd1, 0xb8, 0xe4, 0x08, 0x6e, 0x86, 0x8a, 0xff, 0x85, 0x23, 0xf4, 0xe6, 0xef, - 0x7c, 0xfa, 0xb1, 0xbc, 0xff, 0xfc, 0xdf, 0xc2, 0xe3, 0x8b, 0x57, 0x9f, 0x52, 0xa7, 0xdb, 0xa6, - 0x55, 0xc7, 0xad, 0x9d, 0x25, 0x0f, 0x18, 0x3d, 0x07, 0xa7, 0x7d, 0x81, 0xd8, 0x96, 0xb6, 0x67, - 0xb7, 0x9a, 0x5a, 0x17, 0xef, 0x68, 0x06, 0x7d, 0xbc, 0x30, 0x4b, 0xc5, 0x78, 0xd2, 0x23, 0x59, - 0xb7, 0x6e, 0xd8, 0xad, 0xa6, 0x8a, 0x77, 0x2a, 0x24, 0x1b, 0x9d, 0x03, 0x5f, 0x1a, 0x9a, 0xd9, - 0x74, 0x0a, 0xb9, 0x85, 0xf8, 0x85, 0x84, 0x9a, 0xf5, 0x12, 0x6b, 0x4d, 0xa7, 0x98, 0x7a, 0xff, - 0xc7, 0xe6, 0x8f, 0x7d, 0xfe, 0x63, 0xf3, 0xc7, 0x94, 0x65, 0xfa, 0xba, 0x19, 0x1f, 0x5a, 0xd8, - 0x41, 0xd7, 0x20, 0xad, 0x8b, 0x0f, 0x76, 0x69, 0xe9, 0x90, 0xa1, 0xe9, 0x93, 0x2a, 0x9f, 0x94, - 0x20, 0xb9, 0xb4, 0xb5, 0xa1, 0x9b, 0x5d, 0x54, 0x85, 0x69, 0x5f, 0x57, 0xc7, 0x1d, 0xe5, 0xbe, - 0x7a, 0x8b, 0x61, 0xbe, 0x36, 0xec, 0x88, 0x4e, 0xba, 0x7c, 0xf6, 0xb7, 0x3e, 0xfd, 0xd8, 0xfd, - 0x1c, 0x66, 0xab, 0xef, 0xb4, 0x8e, 0xc0, 0xeb, 0x3f, 0xc5, 0x13, 0x68, 0xf3, 0x4d, 0x98, 0x64, - 0x55, 0x75, 0xd0, 0x8b, 0x30, 0xd1, 0x21, 0x7f, 0xf0, 0x00, 0xee, 0x99, 0xa1, 0x3a, 0x4f, 0xe9, - 0x83, 0x1a, 0xc2, 0xf8, 0x94, 0xef, 0x8c, 0x01, 0x2c, 0x6d, 0x6d, 0x35, 0xba, 0x66, 0xa7, 0x85, - 0xdd, 0xb7, 0xab, 0xed, 0x9b, 0x70, 0x3c, 0x70, 0xb7, 0xbc, 0x6b, 0x1c, 0xbd, 0xfd, 0x33, 0xfe, - 0x2d, 0xf3, 0xae, 0x11, 0x09, 0xdb, 0x74, 0x5c, 0x0f, 0x36, 0x7e, 0x74, 0xd8, 0x25, 0xc7, 0x1d, - 0x94, 0xec, 0xcb, 0x90, 0xf1, 0x85, 0xe1, 0xa0, 0x1a, 0xa4, 0x5c, 0xfe, 0x37, 0x17, 0xb0, 0x32, - 0x5c, 0xc0, 0x82, 0x2d, 0x28, 0x64, 0x8f, 0x5d, 0xf9, 0x4b, 0x09, 0x20, 0x30, 0x46, 0xbe, 0x36, - 0x75, 0x0c, 0xd5, 0x20, 0xc9, 0x8d, 0x73, 0xfc, 0x9e, 0x9f, 0x18, 0x65, 0x00, 0x01, 0xa1, 0x7e, - 0x77, 0x0c, 0x66, 0x36, 0xc5, 0xe8, 0xfd, 0xda, 0x97, 0xc1, 0x26, 0x4c, 0x62, 0xcb, 0xed, 0x9a, - 0xde, 0x06, 0xc4, 0xe3, 0xc3, 0xfa, 0x3c, 0xa2, 0x51, 0x55, 0xcb, 0xed, 0x1e, 0x04, 0x35, 0x40, - 0x60, 0x05, 0xe4, 0xf1, 0xe1, 0x38, 0x14, 0x86, 0xb1, 0xa2, 0xf3, 0x90, 0x37, 0xba, 0x98, 0x26, - 0x84, 0xef, 0xd0, 0x4d, 0x89, 0x64, 0x3e, 0xed, 0xa8, 0x40, 0x1c, 0x35, 0xa2, 0x5c, 0x84, 0xf4, - 0xde, 0x3c, 0xb3, 0x29, 0x1f, 0x81, 0x4e, 0x3c, 0x0d, 0xc8, 0x8b, 0x93, 0xf7, 0xdb, 0x7a, 0x4b, - 0xb7, 0x0c, 0xe1, 0xc1, 0x1e, 0x69, 0xce, 0x17, 0xa7, 0xf7, 0xcb, 0x0c, 0x02, 0x55, 0x61, 0x52, - 0xa0, 0x25, 0x8e, 0x8e, 0x26, 0x78, 0xd1, 0x59, 0xc8, 0x06, 0x27, 0x06, 0xea, 0x8d, 0x24, 0xd4, - 0x4c, 0x60, 0x5e, 0x18, 0x35, 0xf3, 0x24, 0x0f, 0x9d, 0x79, 0xb8, 0xc3, 0xf7, 0xc3, 0x71, 0x98, - 0x56, 0x71, 0xf3, 0xaf, 0x7f, 0xb7, 0x6c, 0x00, 0xb0, 0xa1, 0x4a, 0x2c, 0x29, 0xef, 0x99, 0x7b, - 0x18, 0xef, 0x69, 0x06, 0xb2, 0xe4, 0xb8, 0x5f, 0xad, 0x1e, 0xfa, 0xdd, 0x18, 0x64, 0x83, 0x3d, - 0xf4, 0x37, 0x72, 0xd2, 0x42, 0x6b, 0xbe, 0x99, 0x62, 0x77, 0x07, 0x1e, 0x1e, 0x66, 0xa6, 0x06, - 0xb4, 0x79, 0x84, 0x7d, 0xfa, 0x42, 0x1c, 0x92, 0xfc, 0x0c, 0xcf, 0xfa, 0x80, 0x6f, 0x3b, 0xf2, - 0x02, 0x75, 0x4e, 0xdc, 0x41, 0x8f, 0x74, 0x6d, 0x1f, 0x84, 0x29, 0xb2, 0x46, 0x0e, 0x1d, 0x0c, - 0x92, 0x2e, 0xe4, 0xe8, 0x52, 0xd7, 0x3f, 0x18, 0x8b, 0xe6, 0x21, 0x43, 0xc8, 0x7c, 0x3b, 0x4c, - 0x68, 0xa0, 0xad, 0xef, 0x57, 0x59, 0x0a, 0xba, 0x0c, 0x68, 0xcf, 0x0b, 0x5c, 0x68, 0xbe, 0x20, - 0xa4, 0x0b, 0x39, 0xfa, 0x9a, 0xc0, 0xb4, 0x9f, 0x2b, 0x58, 0xee, 0x07, 0x20, 0x35, 0xd1, 0xd8, - 0xcb, 0xda, 0xfc, 0xdd, 0x72, 0x92, 0xb2, 0x44, 0x5f, 0xd7, 0xfe, 0x36, 0x89, 0xb9, 0xc9, 0x7d, - 0xab, 0x69, 0xbe, 0x4a, 0x69, 0x8c, 0x31, 0x30, 0xfe, 0xfc, 0xcd, 0xf9, 0xb9, 0x03, 0xbd, 0xdd, - 0x2a, 0x2a, 0x11, 0x38, 0x4a, 0xd4, 0x02, 0x9f, 0x38, 0xcf, 0xe1, 0xd5, 0x38, 0xaa, 0x81, 0x7c, - 0x0b, 0x1f, 0x68, 0x5d, 0xfe, 0xc3, 0xec, 0xda, 0x0e, 0x16, 0xef, 0x18, 0x9c, 0x5a, 0x8c, 0x78, - 0xe7, 0x7c, 0xb1, 0x62, 0x9b, 0x16, 0xdf, 0xa3, 0x98, 0xba, 0x85, 0x0f, 0x54, 0xce, 0xb7, 0x8c, - 0x71, 0xf1, 0x01, 0x32, 0x5a, 0xde, 0xf8, 0xc3, 0x9f, 0xbd, 0x78, 0x3a, 0xf0, 0x66, 0xf7, 0xbe, - 0x17, 0x27, 0x63, 0x5d, 0x4c, 0x1c, 0x5f, 0xe4, 0x4f, 0x42, 0x81, 0xc3, 0x60, 0x10, 0x58, 0x2b, - 0x48, 0x87, 0xaf, 0x41, 0x7c, 0xfe, 0xd0, 0x1a, 0x24, 0x30, 0x44, 0x5f, 0xf0, 0xe7, 0x80, 0xd8, - 0xa8, 0xd6, 0x04, 0xb5, 0x93, 0x33, 0xd1, 0x91, 0x7f, 0x4c, 0xf9, 0x0f, 0x12, 0x9c, 0x1a, 0xd0, - 0x66, 0xaf, 0xca, 0x06, 0xa0, 0x6e, 0x20, 0x93, 0x6a, 0x85, 0xd8, 0x0f, 0xbc, 0xb7, 0xc1, 0x31, - 0xdd, 0x1d, 0x98, 0x08, 0xde, 0x9e, 0xc9, 0x8c, 0x5b, 0xb2, 0x5f, 0x97, 0x60, 0x36, 0x58, 0x01, - 0xaf, 0x29, 0x75, 0xc8, 0x06, 0x8b, 0xe6, 0x8d, 0x78, 0x60, 0x9c, 0x46, 0x04, 0xeb, 0x1f, 0x02, - 0x41, 0x5b, 0xbe, 0xc5, 0x60, 0xd1, 0xb9, 0xcb, 0x63, 0x0b, 0x45, 0x54, 0x2c, 0xd2, 0x72, 0xb0, - 0xbe, 0xf9, 0x82, 0x04, 0x89, 0x0d, 0xdb, 0x6e, 0xa1, 0xf7, 0xc0, 0xb4, 0x65, 0xbb, 0x1a, 0x19, - 0x59, 0xb8, 0xa9, 0xf1, 0xd0, 0x01, 0xb3, 0xc6, 0xd5, 0x43, 0x65, 0xf5, 0x47, 0x6f, 0xce, 0x0f, - 0x72, 0x46, 0xbd, 0x9b, 0x9f, 0xb7, 0x6c, 0xb7, 0x4c, 0x89, 0x1a, 0x2c, 0xba, 0xb0, 0x03, 0xb9, - 0x70, 0x71, 0xcc, 0x62, 0x97, 0x46, 0x15, 0x97, 0x1b, 0x59, 0x54, 0x76, 0x3b, 0x50, 0x0e, 0x7b, - 0x21, 0xfc, 0x4f, 0x49, 0xcf, 0x7d, 0x13, 0xc8, 0x5b, 0xfd, 0xa7, 0x4d, 0x96, 0x61, 0x52, 0x9c, - 0x2e, 0x91, 0xc6, 0x3d, 0xb9, 0x12, 0x94, 0x27, 0x67, 0xa6, 0xe1, 0xcf, 0xcf, 0xc4, 0xe0, 0x54, - 0xc5, 0xb6, 0x1c, 0x1e, 0xe8, 0xe1, 0xa3, 0x9a, 0xc5, 0x6a, 0x0f, 0xd0, 0xc3, 0x43, 0xc2, 0x50, - 0xd9, 0xc1, 0x60, 0xd3, 0x16, 0xe4, 0xc9, 0x14, 0x6b, 0xd8, 0xd6, 0x5b, 0x8c, 0x35, 0xe5, 0xec, - 0x56, 0x93, 0xd7, 0xe8, 0x16, 0x3e, 0x20, 0xb8, 0x16, 0xbe, 0x13, 0xc2, 0x8d, 0xdf, 0x1b, 0xae, - 0x85, 0xef, 0x04, 0x70, 0xfd, 0x0d, 0xcd, 0x44, 0x68, 0x43, 0xf3, 0x1a, 0xc4, 0x89, 0x29, 0x9c, - 0x38, 0x82, 0xf1, 0x20, 0x0c, 0x81, 0x69, 0xad, 0x0e, 0xa7, 0x78, 0xa4, 0xc0, 0x59, 0xdf, 0xa1, - 0x12, 0xc5, 0xb4, 0x41, 0x2f, 0xe1, 0x83, 0x88, 0xb0, 0x41, 0x76, 0xac, 0xb0, 0xc1, 0xc5, 0x5f, - 0x90, 0x00, 0xfc, 0x98, 0x19, 0x7a, 0x14, 0x4e, 0x96, 0xd7, 0xd7, 0x96, 0xfc, 0xbd, 0x9d, 0xc0, - 0x8f, 0x07, 0x89, 0x77, 0xbc, 0x9c, 0x0e, 0x36, 0xcc, 0x1d, 0x13, 0x37, 0xd1, 0x43, 0x30, 0x1b, - 0xa6, 0x26, 0x5f, 0xd5, 0x25, 0x59, 0x9a, 0xcb, 0xbe, 0x71, 0x77, 0x21, 0xc5, 0xd6, 0x08, 0xb8, - 0x89, 0x2e, 0xc0, 0xf1, 0x41, 0xba, 0xda, 0xda, 0x75, 0x39, 0x36, 0x97, 0x7b, 0xe3, 0xee, 0x42, - 0xda, 0x5b, 0x4c, 0x20, 0x05, 0x50, 0x90, 0x92, 0xe3, 0xc5, 0xe7, 0xe0, 0x8d, 0xbb, 0x0b, 0x49, - 0x36, 0x64, 0xf8, 0xa6, 0xd0, 0x37, 0x02, 0xd4, 0xac, 0x9d, 0xae, 0x6e, 0x50, 0xd3, 0x30, 0x07, - 0x27, 0x6a, 0x6b, 0xcb, 0x6a, 0xa9, 0xd2, 0xa8, 0xad, 0xaf, 0xf5, 0xfd, 0xe6, 0x51, 0x38, 0x6f, - 0x69, 0x7d, 0xb3, 0xbc, 0x52, 0xd5, 0xea, 0xb5, 0xeb, 0x6b, 0x6c, 0x07, 0x37, 0x94, 0xf7, 0xee, - 0xb5, 0x46, 0x6d, 0xb5, 0x2a, 0xc7, 0xca, 0xd7, 0x86, 0x6e, 0xf6, 0xdc, 0x17, 0x1a, 0x8c, 0xfe, - 0x74, 0x14, 0xfa, 0x31, 0x89, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xdf, 0xae, 0x10, 0xc3, 0x37, - 0xa7, 0x00, 0x00, + // 11876 bytes of a gzipped FileDescriptorSet + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6b, 0x94, 0x24, 0xd7, + 0x59, 0xd8, 0x56, 0x77, 0x4f, 0x4f, 0xf7, 0xd7, 0xaf, 0x9a, 0x3b, 0xb3, 0xbb, 0xb3, 0xb3, 0xd2, + 0xce, 0x6c, 0xad, 0xa4, 0x5d, 0xad, 0xa4, 0x59, 0xed, 0x4a, 0xbb, 0x92, 0x5a, 0x96, 0x44, 0xf7, + 0x4c, 0xef, 0x6c, 0xaf, 0xe6, 0xe5, 0xea, 0x9e, 0xb5, 0x24, 0x1e, 0x45, 0x4d, 0xf5, 0x9d, 0x99, + 0xd2, 0x76, 0x57, 0xb5, 0xab, 0xaa, 0x77, 0x77, 0x94, 0x73, 0x72, 0x4c, 0xc0, 0x8e, 0x11, 0x8f, + 0x98, 0x40, 0xc0, 0xd8, 0x5e, 0x23, 0x20, 0x60, 0x1b, 0x02, 0x81, 0xd8, 0x10, 0x1c, 0x4e, 0x1e, + 0xe4, 0x24, 0x04, 0xc8, 0x09, 0x71, 0xf8, 0x11, 0x38, 0x9c, 0x83, 0x02, 0x36, 0xe7, 0xe0, 0x60, + 0x43, 0x80, 0x18, 0x0e, 0x27, 0x3e, 0xc9, 0xc9, 0xb9, 0xaf, 0x7a, 0x74, 0x57, 0x4f, 0xf7, 0xac, + 0x24, 0x43, 0x20, 0x7f, 0x76, 0xa7, 0xee, 0xfd, 0xbe, 0xef, 0xde, 0xfb, 0xdd, 0xef, 0x7e, 0xaf, + 0xfb, 0x68, 0xf8, 0xbd, 0xab, 0xb0, 0xb0, 0x6b, 0xdb, 0xbb, 0x6d, 0x7c, 0xa1, 0xeb, 0xd8, 0x9e, + 0xbd, 0xdd, 0xdb, 0xb9, 0xd0, 0xc2, 0xae, 0xe1, 0x98, 0x5d, 0xcf, 0x76, 0x16, 0x69, 0x19, 0x2a, + 0x31, 0x88, 0x45, 0x01, 0xa1, 0xac, 0xc1, 0xd4, 0x55, 0xb3, 0x8d, 0x97, 0x7d, 0xc0, 0x06, 0xf6, + 0xd0, 0xd3, 0x90, 0xda, 0x31, 0xdb, 0x78, 0x56, 0x5a, 0x48, 0x9e, 0xcb, 0x5d, 0x7a, 0x60, 0xb1, + 0x0f, 0x69, 0x31, 0x8a, 0xb1, 0x49, 0x8a, 0x55, 0x8a, 0xa1, 0xfc, 0x9f, 0x14, 0x4c, 0xc7, 0xd4, + 0x22, 0x04, 0x29, 0x4b, 0xef, 0x10, 0x8a, 0xd2, 0xb9, 0xac, 0x4a, 0xff, 0x46, 0xb3, 0x30, 0xd9, + 0xd5, 0x8d, 0x9b, 0xfa, 0x2e, 0x9e, 0x4d, 0xd0, 0x62, 0xf1, 0x89, 0x4e, 0x01, 0xb4, 0x70, 0x17, + 0x5b, 0x2d, 0x6c, 0x19, 0xfb, 0xb3, 0xc9, 0x85, 0xe4, 0xb9, 0xac, 0x1a, 0x2a, 0x41, 0x8f, 0xc0, + 0x54, 0xb7, 0xb7, 0xdd, 0x36, 0x0d, 0x2d, 0x04, 0x06, 0x0b, 0xc9, 0x73, 0x13, 0xaa, 0xcc, 0x2a, + 0x96, 0x03, 0xe0, 0xb3, 0x50, 0xba, 0x8d, 0xf5, 0x9b, 0x61, 0xd0, 0x1c, 0x05, 0x2d, 0x92, 0xe2, + 0x10, 0xe0, 0x12, 0xe4, 0x3b, 0xd8, 0x75, 0xf5, 0x5d, 0xac, 0x79, 0xfb, 0x5d, 0x3c, 0x9b, 0xa2, + 0xa3, 0x5f, 0x18, 0x18, 0x7d, 0xff, 0xc8, 0x73, 0x1c, 0xab, 0xb9, 0xdf, 0xc5, 0xa8, 0x02, 0x59, + 0x6c, 0xf5, 0x3a, 0x8c, 0xc2, 0xc4, 0x10, 0xfe, 0xd5, 0xac, 0x5e, 0xa7, 0x9f, 0x4a, 0x86, 0xa0, + 0x71, 0x12, 0x93, 0x2e, 0x76, 0x6e, 0x99, 0x06, 0x9e, 0x4d, 0x53, 0x02, 0x67, 0x07, 0x08, 0x34, + 0x58, 0x7d, 0x3f, 0x0d, 0x81, 0x87, 0x96, 0x20, 0x8b, 0xef, 0x78, 0xd8, 0x72, 0x4d, 0xdb, 0x9a, + 0x9d, 0xa4, 0x44, 0x1e, 0x8c, 0x99, 0x45, 0xdc, 0x6e, 0xf5, 0x93, 0x08, 0xf0, 0xd0, 0x15, 0x98, + 0xb4, 0xbb, 0x9e, 0x69, 0x5b, 0xee, 0x6c, 0x66, 0x41, 0x3a, 0x97, 0xbb, 0x74, 0x5f, 0xac, 0x20, + 0x6c, 0x30, 0x18, 0x55, 0x00, 0xa3, 0x3a, 0xc8, 0xae, 0xdd, 0x73, 0x0c, 0xac, 0x19, 0x76, 0x0b, + 0x6b, 0xa6, 0xb5, 0x63, 0xcf, 0x66, 0x29, 0x81, 0xf9, 0xc1, 0x81, 0x50, 0xc0, 0x25, 0xbb, 0x85, + 0xeb, 0xd6, 0x8e, 0xad, 0x16, 0xdd, 0xc8, 0x37, 0x3a, 0x06, 0x69, 0x77, 0xdf, 0xf2, 0xf4, 0x3b, + 0xb3, 0x79, 0x2a, 0x21, 0xfc, 0x8b, 0x88, 0x0e, 0x6e, 0x99, 0xa4, 0xb9, 0xd9, 0x02, 0x13, 0x1d, + 0xfe, 0xa9, 0x7c, 0x36, 0x0d, 0xa5, 0x71, 0x84, 0xef, 0x59, 0x98, 0xd8, 0x21, 0xe3, 0x9f, 0x4d, + 0x1c, 0x86, 0x3b, 0x0c, 0x27, 0xca, 0xde, 0xf4, 0x3d, 0xb2, 0xb7, 0x02, 0x39, 0x0b, 0xbb, 0x1e, + 0x6e, 0x31, 0x59, 0x49, 0x8e, 0x29, 0x6d, 0xc0, 0x90, 0x06, 0x85, 0x2d, 0x75, 0x4f, 0xc2, 0xf6, + 0x12, 0x94, 0xfc, 0x2e, 0x69, 0x8e, 0x6e, 0xed, 0x0a, 0xa9, 0xbd, 0x30, 0xaa, 0x27, 0x8b, 0x35, + 0x81, 0xa7, 0x12, 0x34, 0xb5, 0x88, 0x23, 0xdf, 0x68, 0x19, 0xc0, 0xb6, 0xb0, 0xbd, 0xa3, 0xb5, + 0xb0, 0xd1, 0x9e, 0xcd, 0x0c, 0xe1, 0xd2, 0x06, 0x01, 0x19, 0xe0, 0x92, 0xcd, 0x4a, 0x8d, 0x36, + 0x7a, 0x26, 0x10, 0xc2, 0xc9, 0x21, 0x32, 0xb4, 0xc6, 0x96, 0xdf, 0x80, 0x1c, 0x6e, 0x41, 0xd1, + 0xc1, 0x64, 0x45, 0xe0, 0x16, 0x1f, 0x59, 0x96, 0x76, 0x62, 0x71, 0xe4, 0xc8, 0x54, 0x8e, 0xc6, + 0x06, 0x56, 0x70, 0xc2, 0x9f, 0xe8, 0x0c, 0xf8, 0x05, 0x1a, 0x15, 0x2b, 0xa0, 0xfa, 0x29, 0x2f, + 0x0a, 0xd7, 0xf5, 0x0e, 0x9e, 0x7b, 0x0d, 0x8a, 0x51, 0xf6, 0xa0, 0x19, 0x98, 0x70, 0x3d, 0xdd, + 0xf1, 0xa8, 0x14, 0x4e, 0xa8, 0xec, 0x03, 0xc9, 0x90, 0xc4, 0x56, 0x8b, 0xea, 0xbf, 0x09, 0x95, + 0xfc, 0x89, 0xbe, 0x2e, 0x18, 0x70, 0x92, 0x0e, 0xf8, 0xa1, 0xc1, 0x19, 0x8d, 0x50, 0xee, 0x1f, + 0xf7, 0xdc, 0x53, 0x50, 0x88, 0x0c, 0x60, 0xdc, 0xa6, 0x95, 0x9f, 0x4a, 0xc1, 0xd1, 0x58, 0xda, + 0xe8, 0x25, 0x98, 0xe9, 0x59, 0xa6, 0xe5, 0x61, 0xa7, 0xeb, 0x60, 0x22, 0xb2, 0xac, 0xad, 0xd9, + 0x3f, 0x98, 0x1c, 0x22, 0x74, 0x5b, 0x61, 0x68, 0x46, 0x45, 0x9d, 0xee, 0x0d, 0x16, 0xa2, 0x97, + 0x21, 0x47, 0xe4, 0x43, 0x77, 0x74, 0x4a, 0x90, 0xad, 0xc6, 0x4b, 0xe3, 0x0d, 0x79, 0x71, 0x39, + 0xc0, 0xac, 0x26, 0x3f, 0x28, 0x25, 0xd4, 0x30, 0x2d, 0xb4, 0x07, 0xf9, 0x5b, 0xd8, 0x31, 0x77, + 0x4c, 0x83, 0xd1, 0x26, 0xec, 0x2c, 0x5e, 0x7a, 0x7a, 0x4c, 0xda, 0x37, 0x42, 0xa8, 0x0d, 0x4f, + 0xf7, 0x70, 0x19, 0xb6, 0xd6, 0x6f, 0xd4, 0xd4, 0xfa, 0xd5, 0x7a, 0x6d, 0x59, 0x8d, 0x50, 0x9e, + 0xfb, 0xb4, 0x04, 0xb9, 0x50, 0x5f, 0x88, 0xda, 0xb2, 0x7a, 0x9d, 0x6d, 0xec, 0x70, 0x8e, 0xf3, + 0x2f, 0x74, 0x12, 0xb2, 0x3b, 0xbd, 0x76, 0x9b, 0x89, 0x0d, 0xb3, 0x79, 0x19, 0x52, 0x40, 0x44, + 0x86, 0x68, 0x29, 0xae, 0x08, 0xa8, 0x96, 0x22, 0x7f, 0xa3, 0x33, 0x90, 0x33, 0x5d, 0xcd, 0xc1, + 0x5d, 0xac, 0x7b, 0xb8, 0x35, 0x9b, 0x5a, 0x90, 0xce, 0x65, 0xaa, 0x89, 0x59, 0x49, 0x05, 0xd3, + 0x55, 0x79, 0x29, 0x9a, 0x83, 0x8c, 0x90, 0xbd, 0xd9, 0x09, 0x02, 0xa1, 0xfa, 0xdf, 0xac, 0x8e, + 0x63, 0xa7, 0x45, 0x1d, 0xfb, 0x56, 0x9e, 0x84, 0xa9, 0x81, 0x41, 0xa2, 0x12, 0xe4, 0x96, 0x6b, + 0x4b, 0xab, 0x15, 0xb5, 0xd2, 0xac, 0x6f, 0xac, 0xcb, 0x47, 0x50, 0x11, 0x42, 0xe3, 0x96, 0xa5, + 0xf3, 0xd9, 0xcc, 0x17, 0x27, 0xe5, 0xf7, 0xbd, 0xef, 0x7d, 0xef, 0x4b, 0x28, 0xbf, 0x94, 0x86, + 0x99, 0x38, 0x2d, 0x17, 0xab, 0x70, 0x03, 0x9e, 0x24, 0x23, 0x3c, 0xa9, 0xc0, 0x44, 0x5b, 0xdf, + 0xc6, 0x6d, 0x3a, 0xb8, 0xe2, 0xa5, 0x47, 0xc6, 0xd2, 0xa3, 0x8b, 0xab, 0x04, 0x45, 0x65, 0x98, + 0xe8, 0x79, 0xce, 0xb9, 0x09, 0x4a, 0xe1, 0xfc, 0x78, 0x14, 0x88, 0xf6, 0xe3, 0x5c, 0x3e, 0x09, + 0x59, 0xf2, 0x3f, 0x9b, 0x96, 0x34, 0x9b, 0x16, 0x52, 0x40, 0xa7, 0x65, 0x0e, 0x32, 0x54, 0xb1, + 0xb5, 0xb0, 0x3f, 0x65, 0xe2, 0x9b, 0xa8, 0x82, 0x16, 0xde, 0xd1, 0x7b, 0x6d, 0x4f, 0xbb, 0xa5, + 0xb7, 0x7b, 0x98, 0xaa, 0xa8, 0xac, 0x9a, 0xe7, 0x85, 0x37, 0x48, 0x19, 0x9a, 0x87, 0x1c, 0xd3, + 0x83, 0xa6, 0xd5, 0xc2, 0x77, 0xa8, 0x25, 0x9c, 0x50, 0x99, 0x6a, 0xac, 0x93, 0x12, 0xd2, 0xfc, + 0xab, 0xae, 0x6d, 0x09, 0x65, 0x42, 0x9b, 0x20, 0x05, 0xb4, 0xf9, 0xa7, 0xfa, 0x8d, 0xf0, 0xfd, + 0xf1, 0xc3, 0x1b, 0xd0, 0x7e, 0x67, 0xa1, 0x44, 0x21, 0x9e, 0xe0, 0x6b, 0x55, 0x6f, 0xcf, 0x4e, + 0x51, 0x01, 0x28, 0xb2, 0xe2, 0x0d, 0x5e, 0xaa, 0xfc, 0x7c, 0x02, 0x52, 0xd4, 0x14, 0x94, 0x20, + 0xd7, 0x7c, 0x79, 0xb3, 0xa6, 0x2d, 0x6f, 0x6c, 0x55, 0x57, 0x6b, 0xb2, 0x44, 0xa6, 0x9e, 0x16, + 0x5c, 0x5d, 0xdd, 0xa8, 0x34, 0xe5, 0x84, 0xff, 0x5d, 0x5f, 0x6f, 0x5e, 0x79, 0x52, 0x4e, 0xfa, + 0x08, 0x5b, 0xac, 0x20, 0x15, 0x06, 0x78, 0xe2, 0x92, 0x3c, 0x81, 0x64, 0xc8, 0x33, 0x02, 0xf5, + 0x97, 0x6a, 0xcb, 0x57, 0x9e, 0x94, 0xd3, 0xd1, 0x92, 0x27, 0x2e, 0xc9, 0x93, 0xa8, 0x00, 0x59, + 0x5a, 0x52, 0xdd, 0xd8, 0x58, 0x95, 0x33, 0x3e, 0xcd, 0x46, 0x53, 0xad, 0xaf, 0xaf, 0xc8, 0x59, + 0x9f, 0xe6, 0x8a, 0xba, 0xb1, 0xb5, 0x29, 0x83, 0x4f, 0x61, 0xad, 0xd6, 0x68, 0x54, 0x56, 0x6a, + 0x72, 0xce, 0x87, 0xa8, 0xbe, 0xdc, 0xac, 0x35, 0xe4, 0x7c, 0xa4, 0x5b, 0x4f, 0x5c, 0x92, 0x0b, + 0x7e, 0x13, 0xb5, 0xf5, 0xad, 0x35, 0xb9, 0x88, 0xa6, 0xa0, 0xc0, 0x9a, 0x10, 0x9d, 0x28, 0xf5, + 0x15, 0x5d, 0x79, 0x52, 0x96, 0x83, 0x8e, 0x30, 0x2a, 0x53, 0x91, 0x82, 0x2b, 0x4f, 0xca, 0x48, + 0x59, 0x82, 0x09, 0x2a, 0x86, 0x08, 0x41, 0x71, 0xb5, 0x52, 0xad, 0xad, 0x6a, 0x1b, 0x9b, 0x64, + 0xd1, 0x54, 0x56, 0x65, 0x29, 0x28, 0x53, 0x6b, 0xef, 0xde, 0xaa, 0xab, 0xb5, 0x65, 0x39, 0x11, + 0x2e, 0xdb, 0xac, 0x55, 0x9a, 0xb5, 0x65, 0x39, 0xa9, 0x18, 0x30, 0x13, 0x67, 0x02, 0x63, 0x97, + 0x50, 0x48, 0x16, 0x12, 0x43, 0x64, 0x81, 0xd2, 0xea, 0x97, 0x05, 0xe5, 0x0b, 0x09, 0x98, 0x8e, + 0x71, 0x03, 0x62, 0x1b, 0x79, 0x01, 0x26, 0x98, 0x2c, 0x33, 0x55, 0xfc, 0x70, 0xac, 0x3f, 0x41, + 0x25, 0x7b, 0xc0, 0x39, 0xa2, 0x78, 0x61, 0xb7, 0x31, 0x39, 0xc4, 0x6d, 0x24, 0x24, 0x06, 0x04, + 0xf6, 0x1b, 0x07, 0xcc, 0x35, 0xf3, 0x68, 0xae, 0x8c, 0xe3, 0xd1, 0xd0, 0xb2, 0xc3, 0x99, 0xed, + 0x89, 0x18, 0xb3, 0xfd, 0x2c, 0x4c, 0x0d, 0x10, 0x1a, 0xdb, 0x7c, 0x7e, 0xab, 0x04, 0xb3, 0xc3, + 0x98, 0x33, 0x42, 0x25, 0x26, 0x22, 0x2a, 0xf1, 0xd9, 0x7e, 0x0e, 0x9e, 0x1e, 0x3e, 0x09, 0x03, + 0x73, 0xfd, 0x09, 0x09, 0x8e, 0xc5, 0x87, 0x07, 0xb1, 0x7d, 0x78, 0x1e, 0xd2, 0x1d, 0xec, 0xed, + 0xd9, 0xc2, 0x11, 0x7e, 0x28, 0xc6, 0xbd, 0x22, 0xd5, 0xfd, 0x93, 0xcd, 0xb1, 0xc2, 0xfe, 0x59, + 0x72, 0x98, 0x8f, 0xcf, 0x7a, 0x33, 0xd0, 0xd3, 0x6f, 0x4f, 0xc0, 0xd1, 0x58, 0xe2, 0xb1, 0x1d, + 0xbd, 0x1f, 0xc0, 0xb4, 0xba, 0x3d, 0x8f, 0x39, 0xbb, 0x4c, 0x13, 0x67, 0x69, 0x09, 0x55, 0x5e, + 0x44, 0xcb, 0xf6, 0x3c, 0xbf, 0x9e, 0x19, 0x51, 0x60, 0x45, 0x14, 0xe0, 0xe9, 0xa0, 0xa3, 0x29, + 0xda, 0xd1, 0x53, 0x43, 0x46, 0x3a, 0x20, 0x98, 0x8f, 0x83, 0x6c, 0xb4, 0x4d, 0x6c, 0x79, 0x9a, + 0xeb, 0x39, 0x58, 0xef, 0x98, 0xd6, 0x2e, 0xb3, 0xb3, 0xe5, 0x89, 0x1d, 0xbd, 0xed, 0x62, 0xb5, + 0xc4, 0xaa, 0x1b, 0xa2, 0x96, 0x60, 0x50, 0x01, 0x72, 0x42, 0x18, 0xe9, 0x08, 0x06, 0xab, 0xf6, + 0x31, 0x94, 0xef, 0xc9, 0x42, 0x2e, 0x14, 0x4c, 0xa1, 0xd3, 0x90, 0x7f, 0x55, 0xbf, 0xa5, 0x6b, + 0x22, 0x40, 0x66, 0x9c, 0xc8, 0x91, 0xb2, 0x4d, 0x1e, 0x24, 0x3f, 0x0e, 0x33, 0x14, 0xc4, 0xee, + 0x79, 0xd8, 0xd1, 0x8c, 0xb6, 0xee, 0xba, 0x94, 0x69, 0x19, 0x0a, 0x8a, 0x48, 0xdd, 0x06, 0xa9, + 0x5a, 0x12, 0x35, 0xe8, 0x32, 0x4c, 0x53, 0x8c, 0x4e, 0xaf, 0xed, 0x99, 0xdd, 0x36, 0xd6, 0x48, + 0xc8, 0xee, 0x52, 0x93, 0xe3, 0xf7, 0x6c, 0x8a, 0x40, 0xac, 0x71, 0x00, 0xd2, 0x23, 0x17, 0x2d, + 0xc3, 0xfd, 0x14, 0x6d, 0x17, 0x5b, 0xd8, 0xd1, 0x3d, 0xac, 0xe1, 0xf7, 0xf6, 0xf4, 0xb6, 0xab, + 0xe9, 0x56, 0x4b, 0xdb, 0xd3, 0xdd, 0xbd, 0xd9, 0x19, 0xdf, 0x2d, 0x39, 0x41, 0x00, 0x57, 0x38, + 0x5c, 0x8d, 0x82, 0x55, 0xac, 0xd6, 0x35, 0xdd, 0xdd, 0x43, 0x65, 0x38, 0x46, 0xa9, 0xb8, 0x9e, + 0x63, 0x5a, 0xbb, 0x9a, 0xb1, 0x87, 0x8d, 0x9b, 0x5a, 0xcf, 0xdb, 0x79, 0x7a, 0xf6, 0x64, 0xb8, + 0x7d, 0xda, 0xc3, 0x06, 0x85, 0x59, 0x22, 0x20, 0x5b, 0xde, 0xce, 0xd3, 0xa8, 0x01, 0x79, 0x32, + 0x19, 0x1d, 0xf3, 0x35, 0xac, 0xed, 0xd8, 0x0e, 0xb5, 0xa1, 0xc5, 0x18, 0xd5, 0x14, 0xe2, 0xe0, + 0xe2, 0x06, 0x47, 0x58, 0xb3, 0x5b, 0xb8, 0x3c, 0xd1, 0xd8, 0xac, 0xd5, 0x96, 0xd5, 0x9c, 0xa0, + 0x72, 0xd5, 0x76, 0x88, 0x40, 0xed, 0xda, 0x3e, 0x83, 0x73, 0x4c, 0xa0, 0x76, 0x6d, 0xc1, 0xde, + 0xcb, 0x30, 0x6d, 0x18, 0x6c, 0xcc, 0xa6, 0xa1, 0xf1, 0xc0, 0xda, 0x9d, 0x95, 0x23, 0xcc, 0x32, + 0x8c, 0x15, 0x06, 0xc0, 0x65, 0xdc, 0x45, 0xcf, 0xc0, 0xd1, 0x80, 0x59, 0x61, 0xc4, 0xa9, 0x81, + 0x51, 0xf6, 0xa3, 0x5e, 0x86, 0xe9, 0xee, 0xfe, 0x20, 0x22, 0x8a, 0xb4, 0xd8, 0xdd, 0xef, 0x47, + 0x7b, 0x0a, 0x66, 0xba, 0x7b, 0xdd, 0x41, 0xbc, 0xf3, 0x61, 0x3c, 0xd4, 0xdd, 0xeb, 0xf6, 0x23, + 0x3e, 0x48, 0xb3, 0x2c, 0x0e, 0x36, 0xa8, 0x77, 0x78, 0x3c, 0x0c, 0x1e, 0xaa, 0x40, 0x8b, 0x20, + 0x1b, 0x86, 0x86, 0x2d, 0x7d, 0xbb, 0x8d, 0x35, 0xdd, 0xc1, 0x96, 0xee, 0xce, 0xce, 0x53, 0xe0, + 0x94, 0xe7, 0xf4, 0xb0, 0x5a, 0x34, 0x8c, 0x1a, 0xad, 0xac, 0xd0, 0x3a, 0x74, 0x1e, 0xa6, 0xec, + 0xed, 0x57, 0x0d, 0x26, 0x91, 0x5a, 0xd7, 0xc1, 0x3b, 0xe6, 0x9d, 0xd9, 0x07, 0x28, 0x7b, 0x4b, + 0xa4, 0x82, 0xca, 0xe3, 0x26, 0x2d, 0x46, 0x0f, 0x83, 0x6c, 0xb8, 0x7b, 0xba, 0xd3, 0xa5, 0x2a, + 0xd9, 0xed, 0xea, 0x06, 0x9e, 0x7d, 0x90, 0x81, 0xb2, 0xf2, 0x75, 0x51, 0x4c, 0x56, 0x84, 0x7b, + 0xdb, 0xdc, 0xf1, 0x04, 0xc5, 0xb3, 0x6c, 0x45, 0xd0, 0x32, 0x4e, 0xed, 0x1c, 0xc8, 0x84, 0x13, + 0x91, 0x86, 0xcf, 0x51, 0xb0, 0x62, 0x77, 0xaf, 0x1b, 0x6e, 0xf7, 0x0c, 0x14, 0x08, 0x64, 0xd0, + 0xe8, 0xc3, 0xcc, 0x71, 0xeb, 0xee, 0x85, 0x5a, 0x7c, 0x12, 0x8e, 0x11, 0xa0, 0x0e, 0xf6, 0xf4, + 0x96, 0xee, 0xe9, 0x21, 0xe8, 0x47, 0x29, 0x34, 0x61, 0xfb, 0x1a, 0xaf, 0x8c, 0xf4, 0xd3, 0xe9, + 0x6d, 0xef, 0xfb, 0x82, 0xf5, 0x18, 0xeb, 0x27, 0x29, 0x13, 0xa2, 0xf5, 0x8e, 0x45, 0x53, 0x4a, + 0x19, 0xf2, 0x61, 0xb9, 0x47, 0x59, 0x60, 0x92, 0x2f, 0x4b, 0xc4, 0x09, 0x5a, 0xda, 0x58, 0x26, + 0xee, 0xcb, 0x2b, 0x35, 0x39, 0x41, 0xdc, 0xa8, 0xd5, 0x7a, 0xb3, 0xa6, 0xa9, 0x5b, 0xeb, 0xcd, + 0xfa, 0x5a, 0x4d, 0x4e, 0x86, 0x1c, 0xfb, 0xeb, 0xa9, 0xcc, 0x43, 0xf2, 0x59, 0xe5, 0x17, 0x93, + 0x50, 0x8c, 0xc6, 0xd6, 0xe8, 0x5d, 0x70, 0x5c, 0xa4, 0xc8, 0x5c, 0xec, 0x69, 0xb7, 0x4d, 0x87, + 0x2e, 0xc8, 0x8e, 0xce, 0x8c, 0xa3, 0x2f, 0x3f, 0x33, 0x1c, 0xaa, 0x81, 0xbd, 0xf7, 0x98, 0x0e, + 0x59, 0x6e, 0x1d, 0xdd, 0x43, 0xab, 0x30, 0x6f, 0xd9, 0x9a, 0xeb, 0xe9, 0x56, 0x4b, 0x77, 0x5a, + 0x5a, 0x90, 0x9c, 0xd4, 0x74, 0xc3, 0xc0, 0xae, 0x6b, 0x33, 0x43, 0xe8, 0x53, 0xb9, 0xcf, 0xb2, + 0x1b, 0x1c, 0x38, 0xb0, 0x10, 0x15, 0x0e, 0xda, 0x27, 0xbe, 0xc9, 0x61, 0xe2, 0x7b, 0x12, 0xb2, + 0x1d, 0xbd, 0xab, 0x61, 0xcb, 0x73, 0xf6, 0xa9, 0x7f, 0x9e, 0x51, 0x33, 0x1d, 0xbd, 0x5b, 0x23, + 0xdf, 0xe8, 0x06, 0x3c, 0x14, 0x80, 0x6a, 0x6d, 0xbc, 0xab, 0x1b, 0xfb, 0x1a, 0x75, 0xc6, 0x69, + 0xa2, 0x47, 0x33, 0x6c, 0x6b, 0xa7, 0x6d, 0x1a, 0x9e, 0x4b, 0xf5, 0x03, 0xd3, 0x71, 0x4a, 0x80, + 0xb1, 0x4a, 0x11, 0xae, 0xbb, 0xb6, 0x45, 0x7d, 0xf0, 0x25, 0x01, 0xfd, 0xce, 0xcd, 0x70, 0x74, + 0x96, 0x52, 0xf2, 0xc4, 0xf5, 0x54, 0x66, 0x42, 0x4e, 0x5f, 0x4f, 0x65, 0xd2, 0xf2, 0xe4, 0xf5, + 0x54, 0x26, 0x23, 0x67, 0xaf, 0xa7, 0x32, 0x59, 0x19, 0x94, 0xf7, 0x67, 0x21, 0x1f, 0x8e, 0x0c, + 0x48, 0xa0, 0x65, 0x50, 0xdb, 0x28, 0x51, 0xed, 0x79, 0xe6, 0xc0, 0x38, 0x62, 0x71, 0x89, 0x18, + 0xcd, 0x72, 0x9a, 0xb9, 0xe1, 0x2a, 0xc3, 0x24, 0x0e, 0x0b, 0x11, 0x6b, 0xcc, 0xdc, 0x9e, 0x8c, + 0xca, 0xbf, 0xd0, 0x0a, 0xa4, 0x5f, 0x75, 0x29, 0xed, 0x34, 0xa5, 0xfd, 0xc0, 0xc1, 0xb4, 0xaf, + 0x37, 0x28, 0xf1, 0xec, 0xf5, 0x86, 0xb6, 0xbe, 0xa1, 0xae, 0x55, 0x56, 0x55, 0x8e, 0x8e, 0x4e, + 0x40, 0xaa, 0xad, 0xbf, 0xb6, 0x1f, 0x35, 0xaf, 0xb4, 0x08, 0x2d, 0x42, 0xa9, 0x67, 0xb1, 0xa8, + 0x9b, 0x4c, 0x15, 0x81, 0x2a, 0x85, 0xa1, 0x8a, 0x41, 0xed, 0x2a, 0x81, 0x1f, 0x53, 0x3c, 0x4e, + 0x40, 0xea, 0x36, 0xd6, 0x6f, 0x46, 0x8d, 0x20, 0x2d, 0x42, 0xe7, 0x20, 0xdf, 0xc2, 0xdb, 0xbd, + 0x5d, 0xcd, 0xc1, 0x2d, 0xdd, 0xf0, 0xa2, 0xaa, 0x3f, 0x47, 0xab, 0x54, 0x5a, 0x83, 0x5e, 0x84, + 0x2c, 0x99, 0x23, 0x8b, 0xce, 0xf1, 0x14, 0x65, 0xc1, 0x63, 0x07, 0xb3, 0x80, 0x4f, 0xb1, 0x40, + 0x52, 0x03, 0x7c, 0x74, 0x1d, 0xd2, 0x9e, 0xee, 0xec, 0x62, 0x8f, 0x6a, 0xfe, 0x62, 0x4c, 0xba, + 0x2a, 0x86, 0x52, 0x93, 0x62, 0x10, 0xb6, 0x52, 0x19, 0xe5, 0x14, 0xd0, 0x35, 0x98, 0x64, 0x7f, + 0xb9, 0xb3, 0xd3, 0x0b, 0xc9, 0xc3, 0x13, 0x53, 0x05, 0xfa, 0x3b, 0xa8, 0xb3, 0x2e, 0xc0, 0x04, + 0x15, 0x36, 0x04, 0xc0, 0xc5, 0x4d, 0x3e, 0x82, 0x32, 0x90, 0x5a, 0xda, 0x50, 0x89, 0xde, 0x92, + 0x21, 0xcf, 0x4a, 0xb5, 0xcd, 0x7a, 0x6d, 0xa9, 0x26, 0x27, 0x94, 0xcb, 0x90, 0x66, 0x12, 0x44, + 0x74, 0x9a, 0x2f, 0x43, 0xf2, 0x11, 0xfe, 0xc9, 0x69, 0x48, 0xa2, 0x76, 0x6b, 0xad, 0x5a, 0x53, + 0xe5, 0x84, 0xb2, 0x05, 0xa5, 0x3e, 0xae, 0xa3, 0xa3, 0x30, 0xa5, 0xd6, 0x9a, 0xb5, 0x75, 0x12, + 0xb5, 0x69, 0x5b, 0xeb, 0x2f, 0xae, 0x6f, 0xbc, 0x67, 0x5d, 0x3e, 0x12, 0x2d, 0x16, 0x0a, 0x52, + 0x42, 0x33, 0x20, 0x07, 0xc5, 0x8d, 0x8d, 0x2d, 0x95, 0xf6, 0xe6, 0x3b, 0x13, 0x20, 0xf7, 0xb3, + 0x0d, 0x1d, 0x87, 0xe9, 0x66, 0x45, 0x5d, 0xa9, 0x35, 0x35, 0x16, 0x89, 0xfa, 0xa4, 0x67, 0x40, + 0x0e, 0x57, 0x5c, 0xad, 0xd3, 0x40, 0x7b, 0x1e, 0x4e, 0x86, 0x4b, 0x6b, 0x2f, 0x35, 0x6b, 0xeb, + 0x0d, 0xda, 0x78, 0x65, 0x7d, 0x85, 0x68, 0xeb, 0x3e, 0x7a, 0x22, 0xf6, 0x4d, 0x92, 0xae, 0x46, + 0xe9, 0xd5, 0x56, 0x97, 0xe5, 0x54, 0x7f, 0xf1, 0xc6, 0x7a, 0x6d, 0xe3, 0xaa, 0x3c, 0xd1, 0xdf, + 0x3a, 0x8d, 0x87, 0xd3, 0x68, 0x0e, 0x8e, 0xf5, 0x97, 0x6a, 0xb5, 0xf5, 0xa6, 0xfa, 0xb2, 0x3c, + 0xd9, 0xdf, 0x70, 0xa3, 0xa6, 0xde, 0xa8, 0x2f, 0xd5, 0xe4, 0x0c, 0x3a, 0x06, 0x28, 0xda, 0xa3, + 0xe6, 0xb5, 0x8d, 0x65, 0x39, 0x3b, 0xa0, 0x9f, 0x14, 0x17, 0xf2, 0xe1, 0xa0, 0xf4, 0x6b, 0xa2, + 0x1a, 0x95, 0x0f, 0x27, 0x20, 0x17, 0x0a, 0x32, 0x49, 0x74, 0xa0, 0xb7, 0xdb, 0xf6, 0x6d, 0x4d, + 0x6f, 0x9b, 0xba, 0xcb, 0xb5, 0x17, 0xd0, 0xa2, 0x0a, 0x29, 0x19, 0x57, 0x5b, 0x8c, 0x6f, 0x2f, + 0xd2, 0x7f, 0x1d, 0xed, 0xc5, 0x84, 0x9c, 0x56, 0x3e, 0x2e, 0x81, 0xdc, 0x1f, 0x3d, 0xf6, 0x0d, + 0x5f, 0x1a, 0x36, 0xfc, 0xaf, 0xc9, 0xdc, 0x7d, 0x4c, 0x82, 0x62, 0x34, 0x64, 0xec, 0xeb, 0xde, + 0xe9, 0xbf, 0xd2, 0xee, 0xfd, 0x6e, 0x02, 0x0a, 0x91, 0x40, 0x71, 0xdc, 0xde, 0xbd, 0x17, 0xa6, + 0xcc, 0x16, 0xee, 0x74, 0x6d, 0x0f, 0x5b, 0xc6, 0xbe, 0xd6, 0xc6, 0xb7, 0x70, 0x7b, 0x56, 0xa1, + 0x2a, 0xfe, 0xc2, 0xc1, 0xa1, 0xe8, 0x62, 0x3d, 0xc0, 0x5b, 0x25, 0x68, 0xe5, 0xe9, 0xfa, 0x72, + 0x6d, 0x6d, 0x73, 0xa3, 0x59, 0x5b, 0x5f, 0x7a, 0x59, 0x68, 0x17, 0x55, 0x36, 0xfb, 0xc0, 0xde, + 0x41, 0xa5, 0xbd, 0x09, 0x72, 0x7f, 0xa7, 0x88, 0xae, 0x88, 0xe9, 0x96, 0x7c, 0x04, 0x4d, 0x43, + 0x69, 0x7d, 0x43, 0x6b, 0xd4, 0x97, 0x6b, 0x5a, 0xed, 0xea, 0xd5, 0xda, 0x52, 0xb3, 0xc1, 0x92, + 0x8b, 0x3e, 0x74, 0x53, 0x4e, 0x84, 0x59, 0xfc, 0x91, 0x24, 0x4c, 0xc7, 0xf4, 0x04, 0x55, 0x78, + 0x5a, 0x80, 0x65, 0x2a, 0x1e, 0x1b, 0xa7, 0xf7, 0x8b, 0xc4, 0x31, 0xdf, 0xd4, 0x1d, 0x8f, 0x67, + 0x11, 0x1e, 0x06, 0xc2, 0x25, 0xcb, 0x23, 0x7e, 0x82, 0xc3, 0x93, 0xb6, 0x2c, 0x57, 0x50, 0x0a, + 0xca, 0x59, 0xde, 0xf6, 0x51, 0x40, 0x5d, 0xdb, 0x35, 0x3d, 0xf3, 0x16, 0xd6, 0x4c, 0x4b, 0x64, + 0x78, 0x53, 0x0b, 0xd2, 0xb9, 0x94, 0x2a, 0x8b, 0x9a, 0xba, 0xe5, 0xf9, 0xd0, 0x16, 0xde, 0xd5, + 0xfb, 0xa0, 0x89, 0x1f, 0x93, 0x54, 0x65, 0x51, 0xe3, 0x43, 0x9f, 0x86, 0x7c, 0xcb, 0xee, 0x91, + 0x80, 0x8a, 0xc1, 0x11, 0x6d, 0x21, 0xa9, 0x39, 0x56, 0xe6, 0x83, 0xf0, 0x50, 0x39, 0x48, 0x2d, + 0xe7, 0xd5, 0x1c, 0x2b, 0x63, 0x20, 0x67, 0xa1, 0xa4, 0xef, 0xee, 0x3a, 0x84, 0xb8, 0x20, 0xc4, + 0x82, 0xff, 0xa2, 0x5f, 0x4c, 0x01, 0xe7, 0xae, 0x43, 0x46, 0xf0, 0x81, 0xf8, 0xc3, 0x84, 0x13, + 0x5a, 0x97, 0x65, 0xb4, 0x12, 0xe7, 0xb2, 0x6a, 0xc6, 0x12, 0x95, 0xa7, 0x21, 0x6f, 0xba, 0x5a, + 0xb0, 0xb7, 0x99, 0x58, 0x48, 0x9c, 0xcb, 0xa8, 0x39, 0xd3, 0xf5, 0xf7, 0x48, 0x94, 0x4f, 0x24, + 0xa0, 0x18, 0xdd, 0xb5, 0x45, 0xcb, 0x90, 0x69, 0xdb, 0x7c, 0x93, 0x85, 0x1d, 0x19, 0x38, 0x37, + 0x62, 0xa3, 0x77, 0x71, 0x95, 0xc3, 0xab, 0x3e, 0xe6, 0xdc, 0xaf, 0x4b, 0x90, 0x11, 0xc5, 0xe8, + 0x18, 0xa4, 0xba, 0xba, 0xb7, 0x47, 0xc9, 0x4d, 0x54, 0x13, 0xb2, 0xa4, 0xd2, 0x6f, 0x52, 0xee, + 0x76, 0x75, 0xb6, 0x4f, 0xc4, 0xcb, 0xc9, 0x37, 0x99, 0xd7, 0x36, 0xd6, 0x5b, 0x34, 0xb3, 0x60, + 0x77, 0x3a, 0xd8, 0xf2, 0x5c, 0x31, 0xaf, 0xbc, 0x7c, 0x89, 0x17, 0xa3, 0x47, 0x60, 0xca, 0x73, + 0x74, 0xb3, 0x1d, 0x81, 0x4d, 0x51, 0x58, 0x59, 0x54, 0xf8, 0xc0, 0x65, 0x38, 0x21, 0xe8, 0xb6, + 0xb0, 0xa7, 0x1b, 0x7b, 0xb8, 0x15, 0x20, 0xa5, 0x69, 0x06, 0xf1, 0x38, 0x07, 0x58, 0xe6, 0xf5, + 0x02, 0x57, 0xf9, 0x5c, 0x02, 0xa6, 0x44, 0x2e, 0xa4, 0xe5, 0x33, 0x6b, 0x0d, 0x40, 0xb7, 0x2c, + 0xdb, 0x0b, 0xb3, 0x6b, 0x50, 0x94, 0x07, 0xf0, 0x16, 0x2b, 0x3e, 0x92, 0x1a, 0x22, 0x30, 0xf7, + 0x25, 0x09, 0x20, 0xa8, 0x1a, 0xca, 0xb7, 0x79, 0xc8, 0xf1, 0x3d, 0x79, 0x7a, 0xb0, 0x83, 0xa5, + 0xcf, 0x80, 0x15, 0x5d, 0x35, 0xdb, 0x34, 0xc9, 0xb9, 0x8d, 0x77, 0x4d, 0x8b, 0xef, 0xce, 0xb0, + 0x0f, 0x91, 0xe4, 0x4c, 0x05, 0xdb, 0x93, 0x2a, 0x64, 0x5c, 0xdc, 0xd1, 0x2d, 0xcf, 0x34, 0xf8, + 0x7e, 0xcb, 0x95, 0x43, 0x75, 0x7e, 0xb1, 0xc1, 0xb1, 0x55, 0x9f, 0x8e, 0x72, 0x0e, 0x32, 0xa2, + 0x94, 0x38, 0x7e, 0xeb, 0x1b, 0xeb, 0x35, 0xf9, 0x08, 0x9a, 0x84, 0x64, 0xa3, 0xd6, 0x94, 0x25, + 0x12, 0xc4, 0x56, 0x56, 0xeb, 0x95, 0x86, 0x9c, 0xa8, 0xfe, 0x5d, 0x98, 0x36, 0xec, 0x4e, 0x7f, + 0x83, 0x55, 0xb9, 0x2f, 0x81, 0xe8, 0x5e, 0x93, 0x5e, 0x79, 0x8c, 0x03, 0xed, 0xda, 0x6d, 0xdd, + 0xda, 0x5d, 0xb4, 0x9d, 0xdd, 0xe0, 0x58, 0x0c, 0x89, 0x35, 0xdc, 0xd0, 0xe1, 0x98, 0xee, 0xf6, + 0x5f, 0x4a, 0xd2, 0x8f, 0x24, 0x92, 0x2b, 0x9b, 0xd5, 0x9f, 0x48, 0xcc, 0xad, 0x30, 0xc4, 0x4d, + 0x31, 0x1c, 0x15, 0xef, 0xb4, 0xb1, 0x41, 0x3a, 0x0f, 0x1f, 0x4d, 0xc1, 0x94, 0xde, 0x31, 0x2d, + 0xfb, 0x02, 0xfd, 0x97, 0x1f, 0xaa, 0x99, 0xa0, 0x1f, 0x73, 0x23, 0x4f, 0xdf, 0x94, 0xaf, 0x30, + 0x05, 0x86, 0x46, 0xed, 0x61, 0xcf, 0xfe, 0xe9, 0x77, 0xfe, 0xf8, 0x44, 0x90, 0xfb, 0x2c, 0xaf, + 0x81, 0x2c, 0xc2, 0x6e, 0x6c, 0x19, 0x36, 0x91, 0xb6, 0xd1, 0x34, 0xfe, 0x4c, 0xd0, 0x28, 0x71, + 0xdc, 0x1a, 0x47, 0x2d, 0xbf, 0x0b, 0x32, 0x3e, 0x99, 0x83, 0xb7, 0x93, 0x66, 0xff, 0xa7, 0x20, + 0xe2, 0x63, 0x94, 0x5f, 0x00, 0x60, 0xce, 0x0e, 0x4b, 0xcb, 0x1e, 0x8c, 0xff, 0x15, 0x81, 0x9f, + 0xa5, 0x38, 0x44, 0x0b, 0x95, 0x57, 0xa0, 0xd8, 0xb2, 0x2d, 0x4f, 0xb3, 0x3b, 0xa6, 0x87, 0x3b, + 0x5d, 0x6f, 0x7f, 0x14, 0x91, 0x3f, 0x67, 0x44, 0x32, 0x6a, 0x81, 0xe0, 0x6d, 0x08, 0x34, 0xd2, + 0x13, 0xb6, 0xb3, 0x36, 0x4e, 0x4f, 0xfe, 0xc2, 0xef, 0x09, 0xc5, 0x21, 0x3d, 0xa9, 0xd6, 0x7e, + 0xe5, 0xf3, 0xa7, 0xa4, 0xcf, 0x7d, 0xfe, 0x94, 0xf4, 0xbb, 0x9f, 0x3f, 0x25, 0x7d, 0xe8, 0x0b, + 0xa7, 0x8e, 0x7c, 0xee, 0x0b, 0xa7, 0x8e, 0xfc, 0xd6, 0x17, 0x4e, 0x1d, 0x79, 0xe5, 0x91, 0x5d, + 0xd3, 0xdb, 0xeb, 0x6d, 0x2f, 0x1a, 0x76, 0xe7, 0x82, 0x61, 0xbb, 0x1d, 0xdb, 0xe5, 0xff, 0x3d, + 0xe6, 0xb6, 0x6e, 0x72, 0xf9, 0xf1, 0xee, 0x30, 0x29, 0xd8, 0x4e, 0xb3, 0x1d, 0x35, 0xf8, 0xa3, + 0x47, 0x60, 0x66, 0xd7, 0xde, 0xb5, 0xe9, 0xe7, 0x05, 0xf2, 0x17, 0x17, 0x90, 0xac, 0x5f, 0x3a, + 0x86, 0x90, 0xac, 0xc3, 0x34, 0x07, 0xd6, 0xe8, 0xe1, 0x0e, 0x96, 0xc8, 0x42, 0x07, 0xee, 0xa2, + 0xcc, 0xfe, 0xec, 0xef, 0x53, 0x9f, 0x55, 0x9d, 0xe2, 0xa8, 0xa4, 0x8e, 0xe5, 0xba, 0xca, 0x2a, + 0x1c, 0x8d, 0xd0, 0x63, 0x16, 0x04, 0x3b, 0x23, 0x28, 0xfe, 0x7b, 0x4e, 0x71, 0x3a, 0x44, 0xb1, + 0xc1, 0x51, 0xcb, 0x4b, 0x50, 0x38, 0x0c, 0xad, 0x5f, 0xe6, 0xb4, 0xf2, 0x38, 0x4c, 0x64, 0x05, + 0x4a, 0x94, 0x88, 0xd1, 0x73, 0x3d, 0xbb, 0x43, 0xe7, 0xf0, 0x60, 0x32, 0xff, 0xe1, 0xf7, 0x99, + 0x4a, 0x2f, 0x12, 0xb4, 0x25, 0x1f, 0xab, 0x5c, 0x06, 0x7a, 0x9e, 0xa5, 0x85, 0x8d, 0xf6, 0x08, + 0x0a, 0xbf, 0xc2, 0x3b, 0xe2, 0xc3, 0x97, 0x6f, 0xc0, 0x0c, 0xf9, 0x9b, 0x5a, 0xcf, 0x70, 0x4f, + 0x46, 0x6f, 0xb9, 0xcc, 0xfe, 0x97, 0x6f, 0x65, 0x56, 0x63, 0xda, 0x27, 0x10, 0xea, 0x53, 0x68, + 0x16, 0x77, 0xb1, 0xe7, 0x61, 0xc7, 0xd5, 0xf4, 0x76, 0x5c, 0xf7, 0x42, 0x39, 0xeb, 0xd9, 0x1f, + 0xfc, 0x72, 0x74, 0x16, 0x57, 0x18, 0x66, 0xa5, 0xdd, 0x2e, 0x6f, 0xc1, 0xf1, 0x18, 0xa9, 0x18, + 0x83, 0xe6, 0x47, 0x38, 0xcd, 0x99, 0x01, 0xc9, 0x20, 0x64, 0x37, 0x41, 0x94, 0xfb, 0x73, 0x39, + 0x06, 0xcd, 0x8f, 0x72, 0x9a, 0x88, 0xe3, 0x8a, 0x29, 0x25, 0x14, 0xaf, 0xc3, 0xd4, 0x2d, 0xec, + 0x6c, 0xdb, 0x2e, 0xdf, 0x27, 0x18, 0x83, 0xdc, 0xc7, 0x38, 0xb9, 0x12, 0x47, 0xa4, 0x1b, 0x07, + 0x84, 0xd6, 0x33, 0x90, 0xd9, 0xd1, 0x0d, 0x3c, 0x06, 0x89, 0xbb, 0x9c, 0xc4, 0x24, 0x81, 0x27, + 0xa8, 0x15, 0xc8, 0xef, 0xda, 0xdc, 0x81, 0x1a, 0x8d, 0xfe, 0x71, 0x8e, 0x9e, 0x13, 0x38, 0x9c, + 0x44, 0xd7, 0xee, 0xf6, 0xda, 0xc4, 0xbb, 0x1a, 0x4d, 0xe2, 0x87, 0x04, 0x09, 0x81, 0xc3, 0x49, + 0x1c, 0x82, 0xad, 0x6f, 0x08, 0x12, 0x6e, 0x88, 0x9f, 0x2f, 0x40, 0xce, 0xb6, 0xda, 0xfb, 0xb6, + 0x35, 0x4e, 0x27, 0x7e, 0x98, 0x53, 0x00, 0x8e, 0x42, 0x08, 0x3c, 0x0b, 0xd9, 0x71, 0x27, 0xe2, + 0xc7, 0xbe, 0x2c, 0x96, 0x87, 0x98, 0x81, 0x15, 0x28, 0x09, 0x05, 0x65, 0xda, 0xd6, 0x18, 0x24, + 0x7e, 0x9c, 0x93, 0x28, 0x86, 0xd0, 0xf8, 0x30, 0x3c, 0xec, 0x7a, 0xbb, 0x78, 0x1c, 0x22, 0x9f, + 0x10, 0xc3, 0xe0, 0x28, 0x9c, 0x95, 0xdb, 0xd8, 0x32, 0xf6, 0xc6, 0xa3, 0xf0, 0x49, 0xc1, 0x4a, + 0x81, 0x43, 0x48, 0x2c, 0x41, 0xa1, 0xa3, 0x3b, 0xee, 0x9e, 0xde, 0x1e, 0x6b, 0x3a, 0x3e, 0xc5, + 0x69, 0xe4, 0x7d, 0x24, 0xce, 0x91, 0x9e, 0x75, 0x18, 0x32, 0x3f, 0x21, 0x38, 0x12, 0x42, 0xe3, + 0x4b, 0xcf, 0xf5, 0xe8, 0xa6, 0xca, 0x61, 0xa8, 0xfd, 0xa4, 0x58, 0x7a, 0x0c, 0x77, 0x2d, 0x4c, + 0xf1, 0x59, 0xc8, 0xba, 0xe6, 0x6b, 0x63, 0x91, 0xf9, 0x27, 0x62, 0xa6, 0x29, 0x02, 0x41, 0x7e, + 0x19, 0x4e, 0xc4, 0x9a, 0x89, 0x31, 0x88, 0xfd, 0x14, 0x27, 0x76, 0x2c, 0xc6, 0x54, 0x70, 0x95, + 0x70, 0x58, 0x92, 0x3f, 0x2d, 0x54, 0x02, 0xee, 0xa3, 0xb5, 0x49, 0x42, 0x5a, 0x57, 0xdf, 0x39, + 0x1c, 0xd7, 0xfe, 0xa9, 0xe0, 0x1a, 0xc3, 0x8d, 0x70, 0xad, 0x09, 0xc7, 0x38, 0xc5, 0xc3, 0xcd, + 0xeb, 0xcf, 0x08, 0xc5, 0xca, 0xb0, 0xb7, 0xa2, 0xb3, 0xfb, 0xf5, 0x30, 0xe7, 0xb3, 0x53, 0xc4, + 0x4e, 0xae, 0xd6, 0xd1, 0xbb, 0x63, 0x50, 0xfe, 0x59, 0x4e, 0x59, 0x68, 0x7c, 0x3f, 0xf8, 0x72, + 0xd7, 0xf4, 0x2e, 0x21, 0xfe, 0x12, 0xcc, 0x0a, 0xe2, 0x3d, 0xcb, 0xc1, 0x86, 0xbd, 0x6b, 0x99, + 0xaf, 0xe1, 0xd6, 0x18, 0xa4, 0xff, 0x59, 0xdf, 0x54, 0x6d, 0x85, 0xd0, 0x09, 0xe5, 0x3a, 0xc8, + 0xbe, 0xaf, 0xa2, 0x99, 0x9d, 0xae, 0xed, 0x78, 0x23, 0x28, 0x7e, 0x5a, 0xcc, 0x94, 0x8f, 0x57, + 0xa7, 0x68, 0xe5, 0x1a, 0xb0, 0x93, 0x46, 0xe3, 0x8a, 0xe4, 0x67, 0x38, 0xa1, 0x42, 0x80, 0xc5, + 0x15, 0x87, 0x61, 0x77, 0xba, 0xba, 0x33, 0x8e, 0xfe, 0xfb, 0x39, 0xa1, 0x38, 0x38, 0x0a, 0x57, + 0x1c, 0xc4, 0x5f, 0x23, 0xd6, 0x7e, 0x0c, 0x0a, 0x3f, 0x2f, 0x14, 0x87, 0xc0, 0xe1, 0x24, 0x84, + 0xc3, 0x30, 0x06, 0x89, 0x7f, 0x2e, 0x48, 0x08, 0x1c, 0x42, 0xe2, 0xdd, 0x81, 0xa1, 0x75, 0xf0, + 0xae, 0xe9, 0x7a, 0xfc, 0xa8, 0xe0, 0xc1, 0xa4, 0x7e, 0xe1, 0xcb, 0x51, 0x27, 0x4c, 0x0d, 0xa1, + 0x12, 0x4d, 0xc4, 0x3d, 0x7b, 0x1a, 0xd0, 0x8f, 0xee, 0xd8, 0x67, 0x85, 0x26, 0x0a, 0xa1, 0x91, + 0xbe, 0x85, 0x3c, 0x44, 0xc2, 0x76, 0x83, 0x84, 0xb1, 0x63, 0x90, 0xfb, 0x17, 0x7d, 0x9d, 0x6b, + 0x08, 0x5c, 0x42, 0x33, 0xe4, 0xff, 0xf4, 0xac, 0x9b, 0x78, 0x7f, 0x2c, 0xe9, 0xfc, 0xc5, 0x3e, + 0xff, 0x67, 0x8b, 0x61, 0x32, 0x1d, 0x52, 0xea, 0xf3, 0xa7, 0x46, 0x47, 0x40, 0xdf, 0xf2, 0x15, + 0x3e, 0xde, 0xa8, 0x3b, 0x55, 0x5e, 0x25, 0x42, 0x1e, 0x75, 0x7a, 0x46, 0x13, 0xfb, 0xd6, 0xaf, + 0xf8, 0x72, 0x1e, 0xf1, 0x79, 0xca, 0x57, 0xa1, 0x10, 0x71, 0x78, 0x46, 0x93, 0xfa, 0x36, 0x4e, + 0x2a, 0x1f, 0xf6, 0x77, 0xca, 0x97, 0x21, 0x45, 0x9c, 0x97, 0xd1, 0xe8, 0xef, 0xe7, 0xe8, 0x14, + 0xbc, 0xfc, 0x1c, 0x64, 0x84, 0xd3, 0x32, 0x1a, 0xf5, 0x03, 0x1c, 0xd5, 0x47, 0x21, 0xe8, 0xc2, + 0x61, 0x19, 0x8d, 0xfe, 0xf7, 0x05, 0xba, 0x40, 0x21, 0xe8, 0xe3, 0xb3, 0xf0, 0xdf, 0x7c, 0x47, + 0x8a, 0x1b, 0x1d, 0xc1, 0xbb, 0x67, 0x61, 0x92, 0x7b, 0x2a, 0xa3, 0xb1, 0xbf, 0x9d, 0x37, 0x2e, + 0x30, 0xca, 0x4f, 0xc1, 0xc4, 0x98, 0x0c, 0xff, 0x2e, 0x8e, 0xca, 0xe0, 0xcb, 0x4b, 0x90, 0x0b, + 0x79, 0x27, 0xa3, 0xd1, 0xbf, 0x9b, 0xa3, 0x87, 0xb1, 0x48, 0xd7, 0xb9, 0x77, 0x32, 0x9a, 0xc0, + 0x3f, 0x10, 0x5d, 0xe7, 0x18, 0x84, 0x6d, 0xc2, 0x31, 0x19, 0x8d, 0xfd, 0x21, 0xc1, 0x75, 0x81, + 0x52, 0x7e, 0x01, 0xb2, 0xbe, 0xb1, 0x19, 0x8d, 0xff, 0x3d, 0x1c, 0x3f, 0xc0, 0x21, 0x1c, 0x08, + 0x19, 0xbb, 0xd1, 0x24, 0xfe, 0xa1, 0xe0, 0x40, 0x08, 0x8b, 0x2c, 0xa3, 0x7e, 0x07, 0x66, 0x34, + 0xa5, 0xef, 0x15, 0xcb, 0xa8, 0xcf, 0x7f, 0x21, 0xb3, 0x49, 0x75, 0xfe, 0x68, 0x12, 0xdf, 0x27, + 0x66, 0x93, 0xc2, 0x93, 0x6e, 0xf4, 0x7b, 0x04, 0xa3, 0x69, 0xfc, 0x80, 0xe8, 0x46, 0x9f, 0x43, + 0x50, 0xde, 0x04, 0x34, 0xe8, 0x0d, 0x8c, 0xa6, 0xf7, 0x61, 0x4e, 0x6f, 0x6a, 0xc0, 0x19, 0x28, + 0xbf, 0x07, 0x8e, 0xc5, 0x7b, 0x02, 0xa3, 0xa9, 0xfe, 0xe0, 0x57, 0xfa, 0x62, 0xb7, 0xb0, 0x23, + 0x50, 0x6e, 0x06, 0x26, 0x25, 0xec, 0x05, 0x8c, 0x26, 0xfb, 0x91, 0xaf, 0x44, 0x15, 0x77, 0xd8, + 0x09, 0x28, 0x57, 0x00, 0x02, 0x03, 0x3c, 0x9a, 0xd6, 0xc7, 0x38, 0xad, 0x10, 0x12, 0x59, 0x1a, + 0xdc, 0xfe, 0x8e, 0xc6, 0xbf, 0x2b, 0x96, 0x06, 0xc7, 0x20, 0x4b, 0x43, 0x98, 0xde, 0xd1, 0xd8, + 0x1f, 0x17, 0x4b, 0x43, 0xa0, 0x10, 0xc9, 0x0e, 0x59, 0xb7, 0xd1, 0x14, 0x7e, 0x58, 0x48, 0x76, + 0x08, 0xab, 0xbc, 0x0e, 0x53, 0x03, 0x06, 0x71, 0x34, 0xa9, 0x1f, 0xe1, 0xa4, 0xe4, 0x7e, 0x7b, + 0x18, 0x36, 0x5e, 0xdc, 0x18, 0x8e, 0xa6, 0xf6, 0xa3, 0x7d, 0xc6, 0x8b, 0xdb, 0xc2, 0xf2, 0xb3, + 0x90, 0xb1, 0x7a, 0xed, 0x36, 0x59, 0x3c, 0xa3, 0x52, 0x5e, 0xff, 0xfd, 0xab, 0x9c, 0x3b, 0x02, + 0xa1, 0x7c, 0x19, 0x26, 0x70, 0x67, 0x1b, 0xb7, 0x46, 0x61, 0xfe, 0xe1, 0x57, 0x85, 0xc2, 0x24, + 0xd0, 0xe5, 0x17, 0x00, 0x58, 0x6a, 0x84, 0x1e, 0xd2, 0x18, 0x81, 0xfb, 0xa5, 0xaf, 0xf2, 0xc3, + 0x97, 0x01, 0x4a, 0x40, 0x60, 0x9c, 0x4c, 0xdd, 0x97, 0xa3, 0x04, 0xe8, 0x8c, 0x3c, 0x03, 0x93, + 0xaf, 0xba, 0xb6, 0xe5, 0xe9, 0x23, 0x33, 0x96, 0x7f, 0xc4, 0xb1, 0x05, 0x3c, 0x61, 0x58, 0xc7, + 0x76, 0xb0, 0xa7, 0xef, 0xba, 0xa3, 0x70, 0xff, 0x98, 0xe3, 0xfa, 0x08, 0x04, 0xd9, 0xd0, 0x5d, + 0x6f, 0x9c, 0x71, 0xff, 0x0f, 0x81, 0x2c, 0x10, 0x48, 0xa7, 0xc9, 0xdf, 0x37, 0xf1, 0xc8, 0x0c, + 0xe7, 0x9f, 0x88, 0x4e, 0x73, 0xf8, 0xf2, 0x73, 0x90, 0x25, 0x7f, 0xb2, 0x13, 0xd5, 0x23, 0x90, + 0xff, 0x94, 0x23, 0x07, 0x18, 0xa4, 0x65, 0xd7, 0x6b, 0x79, 0xe6, 0x68, 0x66, 0xff, 0x19, 0x9f, + 0x69, 0x01, 0x5f, 0xae, 0x40, 0xce, 0xf5, 0x5a, 0xad, 0x1e, 0xf7, 0x4f, 0x47, 0xe5, 0x87, 0xbf, + 0xea, 0xa7, 0x2c, 0x7c, 0x1c, 0x32, 0xdb, 0xb7, 0x6f, 0x7a, 0x5d, 0x9b, 0xee, 0xc6, 0x8d, 0xcc, + 0x10, 0x73, 0x0a, 0x21, 0x94, 0xf2, 0x12, 0xe4, 0xc9, 0x58, 0xc4, 0x4d, 0x95, 0x91, 0xf9, 0x61, + 0xce, 0x80, 0x08, 0x52, 0xf5, 0x9b, 0x87, 0x25, 0x77, 0xe3, 0xf7, 0x10, 0x60, 0xc5, 0x5e, 0xb1, + 0xd9, 0xee, 0xc1, 0x2b, 0x0f, 0x0e, 0x66, 0x7f, 0xa3, 0x79, 0x5d, 0xfa, 0x17, 0xfc, 0x2f, 0x09, + 0xee, 0x37, 0xec, 0x0e, 0xf6, 0xb6, 0x77, 0xbc, 0x0b, 0x86, 0xb3, 0xdf, 0xf5, 0xec, 0x0b, 0xb7, + 0x2e, 0x5e, 0xb8, 0x89, 0xf7, 0x5d, 0x9e, 0xf8, 0x45, 0xa2, 0x7a, 0x91, 0x55, 0x2f, 0xde, 0xba, + 0x38, 0x17, 0x9b, 0x22, 0x56, 0x5e, 0x82, 0xec, 0x26, 0xbd, 0xb9, 0xfa, 0x22, 0xde, 0x47, 0x73, + 0x30, 0x89, 0x5b, 0x97, 0x2e, 0x5f, 0xbe, 0xf8, 0x0c, 0xdd, 0x8b, 0xcf, 0x5f, 0x3b, 0xa2, 0x8a, + 0x02, 0x74, 0x0a, 0xb2, 0x2e, 0x36, 0xba, 0x97, 0x2e, 0x5f, 0xb9, 0x79, 0x91, 0xee, 0xe3, 0x90, + 0xda, 0xa0, 0xa8, 0x9c, 0xf9, 0xe2, 0x1b, 0xf3, 0xd2, 0x17, 0x7f, 0x78, 0x5e, 0xaa, 0x4e, 0x40, + 0xd2, 0xed, 0x75, 0xaa, 0x6b, 0x43, 0x93, 0xdc, 0x4f, 0x44, 0x86, 0x29, 0xc6, 0x21, 0xfe, 0xd0, + 0xbb, 0xe6, 0x85, 0xc1, 0xd1, 0xf9, 0xc9, 0xee, 0x4f, 0xa5, 0xe0, 0x54, 0xcc, 0xe0, 0xbb, 0x8e, + 0x6d, 0xef, 0x1c, 0x7a, 0xf4, 0x3b, 0x30, 0xb1, 0x49, 0x10, 0xd1, 0x0c, 0x4c, 0x78, 0xb6, 0xa7, + 0xb7, 0xe9, 0xb8, 0x93, 0x2a, 0xfb, 0x20, 0xa5, 0xec, 0xf2, 0x4c, 0x82, 0x95, 0x9a, 0xe2, 0xde, + 0x4c, 0x1b, 0xeb, 0x3b, 0xec, 0x0c, 0x72, 0x92, 0x6e, 0x8f, 0x66, 0x48, 0x01, 0x3d, 0x6e, 0x3c, + 0x03, 0x13, 0x7a, 0x8f, 0xed, 0xec, 0x25, 0xcf, 0xe5, 0x55, 0xf6, 0xa1, 0xac, 0xc2, 0x24, 0x4f, + 0xe1, 0x22, 0x19, 0x92, 0x37, 0xf1, 0x3e, 0xe3, 0xaf, 0x4a, 0xfe, 0x44, 0x17, 0x60, 0x82, 0xf6, + 0x9e, 0x5f, 0xae, 0x38, 0xb1, 0x38, 0xd8, 0xfd, 0x45, 0xda, 0x4b, 0x95, 0xc1, 0x29, 0xd7, 0x21, + 0xb3, 0x6c, 0x77, 0x4c, 0xcb, 0x8e, 0x92, 0xcb, 0x32, 0x72, 0xb4, 0xd3, 0xdd, 0x9e, 0xc7, 0x37, + 0xdb, 0xd8, 0x07, 0x3a, 0x06, 0x69, 0x76, 0x28, 0x9d, 0x6f, 0x4f, 0xf2, 0x2f, 0x65, 0x09, 0x26, + 0x29, 0xed, 0x8d, 0xae, 0x7f, 0x11, 0x4c, 0x0a, 0x5d, 0x04, 0xe3, 0xe4, 0x13, 0x41, 0x6f, 0x11, + 0xa4, 0x5a, 0xba, 0xa7, 0xf3, 0x81, 0xd3, 0xbf, 0x95, 0x17, 0x20, 0xc3, 0x89, 0xb8, 0xe8, 0x09, + 0x48, 0xda, 0x5d, 0x97, 0x6f, 0x30, 0x9e, 0x1c, 0x3a, 0x96, 0x8d, 0x6e, 0x35, 0xf5, 0x2b, 0x6f, + 0xce, 0x1f, 0x51, 0x09, 0xf4, 0x3b, 0x25, 0x2b, 0xdf, 0x9b, 0x80, 0x53, 0x03, 0xfb, 0x1e, 0x5c, + 0x5b, 0x0c, 0xbb, 0x98, 0x5e, 0x86, 0xcc, 0xb2, 0x50, 0x42, 0xb3, 0x30, 0xe9, 0x62, 0xc3, 0xb6, + 0x5a, 0x2e, 0x97, 0x0b, 0xf1, 0x49, 0x98, 0x6c, 0xe9, 0x96, 0xed, 0xf2, 0x1b, 0x14, 0xec, 0xa3, + 0xfa, 0x51, 0xe9, 0x70, 0x6b, 0xbf, 0x20, 0x5a, 0xa2, 0xeb, 0x7f, 0x53, 0x7a, 0xe5, 0xe2, 0xc8, + 0xcd, 0xc3, 0x9b, 0x96, 0x7d, 0xdb, 0xf2, 0x07, 0x11, 0xd9, 0x40, 0x3c, 0xd5, 0xbf, 0x81, 0xf8, + 0x1e, 0xdc, 0x6e, 0xbf, 0x48, 0xe0, 0x9b, 0x04, 0xd5, 0xe7, 0xca, 0xc7, 0x53, 0x83, 0x5c, 0xb9, + 0xed, 0xe8, 0xdd, 0x2e, 0x76, 0xdc, 0x61, 0x5c, 0x39, 0x03, 0xb9, 0xe5, 0xd0, 0x21, 0x81, 0x19, + 0x71, 0x59, 0x47, 0xa2, 0x07, 0x08, 0xd8, 0x87, 0xa2, 0x00, 0x5c, 0x6d, 0xdb, 0xba, 0x17, 0x03, + 0x93, 0x08, 0xc1, 0xd4, 0x2d, 0xef, 0xca, 0x93, 0x31, 0x30, 0x49, 0x01, 0x73, 0x06, 0x72, 0x5b, + 0xc3, 0x80, 0x52, 0x51, 0x42, 0x4f, 0x5c, 0x8a, 0x81, 0x99, 0xe8, 0x23, 0x14, 0x0b, 0x54, 0x10, + 0x40, 0xa7, 0x21, 0x5b, 0xb5, 0xed, 0x76, 0x0c, 0x48, 0x26, 0x44, 0xa7, 0x11, 0x3a, 0xff, 0x10, + 0x01, 0xca, 0x86, 0x3a, 0x54, 0xdd, 0xf7, 0xb0, 0x1b, 0x03, 0x93, 0xe7, 0x30, 0x87, 0x17, 0x90, + 0xf7, 0xf0, 0x79, 0x39, 0xac, 0x80, 0x88, 0xf9, 0xbc, 0x27, 0x01, 0xf9, 0x81, 0x7c, 0x48, 0xc5, + 0x32, 0xaa, 0x44, 0xc3, 0xea, 0x8e, 0xde, 0x11, 0x02, 0x32, 0xe5, 0xaf, 0x6b, 0x5a, 0x3f, 0x54, + 0xc3, 0xce, 0x8d, 0x58, 0x7f, 0x73, 0x23, 0x24, 0x51, 0xf9, 0x6c, 0x12, 0x4a, 0x4b, 0xb6, 0xe5, + 0x62, 0xcb, 0xed, 0xb9, 0x9b, 0xb4, 0x0b, 0xe8, 0x49, 0x98, 0xd8, 0x6e, 0xdb, 0xc6, 0x4d, 0xca, + 0xdb, 0xdc, 0xa5, 0x53, 0x8b, 0x03, 0x9d, 0x59, 0xac, 0x92, 0x7a, 0x06, 0xae, 0x32, 0x60, 0xf4, + 0x1c, 0x64, 0xf0, 0x2d, 0xb3, 0x85, 0x2d, 0x03, 0x73, 0x4d, 0x7b, 0x3a, 0x06, 0xb1, 0xc6, 0x41, + 0x38, 0xae, 0x8f, 0x82, 0xbe, 0x0e, 0xb2, 0xb7, 0xf4, 0xb6, 0xd9, 0xd2, 0x3d, 0xdb, 0xe1, 0x57, + 0x8e, 0x94, 0x18, 0xfc, 0x1b, 0x02, 0x86, 0x13, 0x08, 0x90, 0x50, 0x19, 0x26, 0x6f, 0x61, 0x87, + 0x9e, 0x6f, 0x61, 0x37, 0x81, 0x16, 0xe2, 0xf0, 0x19, 0x04, 0xc7, 0x16, 0x08, 0xe8, 0x32, 0xa4, + 0xf4, 0x6d, 0xc3, 0xa4, 0x47, 0x1f, 0x72, 0x97, 0xee, 0x8f, 0x41, 0xac, 0x54, 0x97, 0xea, 0x0c, + 0x8b, 0x9e, 0xfe, 0xa3, 0xe0, 0xa4, 0xd3, 0xee, 0xbe, 0x65, 0xec, 0x39, 0xb6, 0xb5, 0x4f, 0x0f, + 0xfb, 0xc4, 0x77, 0xba, 0x21, 0x60, 0x44, 0xa7, 0x7d, 0x24, 0xd2, 0xe9, 0x1d, 0xac, 0x7b, 0x3d, + 0x07, 0xf3, 0x7b, 0xf0, 0x71, 0x9d, 0xbe, 0xca, 0x20, 0x44, 0xa7, 0x39, 0x82, 0x52, 0x87, 0x5c, + 0x68, 0x1e, 0xd8, 0x89, 0xf8, 0x3b, 0xda, 0x36, 0x59, 0x24, 0x7c, 0xc1, 0x67, 0x3a, 0xfa, 0x1d, + 0xba, 0x68, 0xd0, 0x71, 0x98, 0x24, 0x95, 0xbb, 0xfc, 0x94, 0x64, 0x52, 0x4d, 0x77, 0xf4, 0x3b, + 0x2b, 0xba, 0x7b, 0x3d, 0x95, 0x49, 0xca, 0x29, 0xe5, 0x53, 0x12, 0x14, 0xa3, 0x53, 0x83, 0x1e, + 0x01, 0x44, 0x30, 0xf4, 0x5d, 0xac, 0x59, 0xbd, 0x8e, 0x46, 0x27, 0x59, 0xd0, 0x2d, 0x75, 0xf4, + 0x3b, 0x95, 0x5d, 0xbc, 0xde, 0xeb, 0xd0, 0x0e, 0xb8, 0x68, 0x0d, 0x64, 0x01, 0x2c, 0x04, 0xd0, + 0x37, 0xb7, 0x03, 0xb7, 0xf2, 0x39, 0x40, 0x35, 0x43, 0x0c, 0xd4, 0x87, 0xff, 0xdb, 0xbc, 0xa4, + 0x16, 0x19, 0x3d, 0xdf, 0x30, 0x44, 0x86, 0x92, 0x8c, 0x0e, 0x45, 0x79, 0x01, 0x4a, 0x7d, 0x52, + 0x80, 0x14, 0x28, 0x74, 0x7b, 0xdb, 0xda, 0x4d, 0xbc, 0x4f, 0xaf, 0x89, 0x31, 0xf3, 0x98, 0x55, + 0x73, 0xdd, 0xde, 0xf6, 0x8b, 0x78, 0x9f, 0xae, 0xbe, 0x72, 0xe6, 0x17, 0x88, 0x03, 0xf5, 0xc6, + 0xbc, 0xa4, 0x3c, 0x02, 0x85, 0x88, 0x18, 0x10, 0x2b, 0xac, 0x77, 0xbb, 0x5c, 0xff, 0x91, 0x3f, + 0x43, 0xc0, 0xaf, 0x40, 0x9e, 0x38, 0x1e, 0xb8, 0xc5, 0x61, 0x1f, 0x82, 0x12, 0x65, 0x85, 0xd6, + 0xcf, 0xeb, 0x02, 0x2d, 0x5e, 0x13, 0x0c, 0x57, 0xa0, 0x10, 0xc0, 0x05, 0x6c, 0xcf, 0x09, 0xa8, + 0x15, 0xdd, 0x55, 0xbe, 0x5f, 0x82, 0x52, 0x9f, 0x6c, 0xa0, 0xe7, 0x20, 0xdb, 0x75, 0xb0, 0x61, + 0xba, 0xec, 0x18, 0xd1, 0x08, 0x16, 0xa6, 0x28, 0xfb, 0x02, 0x0c, 0xb4, 0x0c, 0x05, 0x71, 0xa4, + 0xa4, 0x85, 0xdb, 0xfa, 0xfe, 0xe8, 0x59, 0x60, 0x24, 0xc4, 0x13, 0x29, 0xcb, 0x04, 0x49, 0xf9, + 0x65, 0x09, 0x0a, 0x11, 0xa1, 0x43, 0x2d, 0xb8, 0xff, 0x96, 0xed, 0xe1, 0x70, 0xaa, 0x83, 0x5f, + 0x1d, 0xda, 0xc3, 0xe6, 0xee, 0x9e, 0xc7, 0xbb, 0x7a, 0x72, 0xa0, 0x9d, 0xc0, 0xd0, 0x50, 0x87, + 0x44, 0x52, 0xe7, 0x08, 0x9d, 0x20, 0xe3, 0xc1, 0xee, 0x18, 0x5d, 0xa3, 0x44, 0xd0, 0x06, 0xa0, + 0xee, 0xb6, 0xd7, 0x4f, 0x3a, 0x31, 0x2e, 0x69, 0x99, 0x20, 0x87, 0x09, 0x2a, 0x0d, 0x80, 0x60, + 0xe1, 0xa2, 0xca, 0x38, 0x83, 0x48, 0x1e, 0xd4, 0xc3, 0x72, 0x62, 0x56, 0xaa, 0x6e, 0x7e, 0xf2, + 0xf3, 0xa7, 0x86, 0x1a, 0x9a, 0x57, 0x2e, 0x8d, 0xef, 0x51, 0x09, 0xdd, 0xef, 0x5b, 0x86, 0xbf, + 0x48, 0xc3, 0xe9, 0x41, 0xcb, 0xe0, 0xab, 0xb8, 0xc3, 0x1a, 0x87, 0x83, 0xa3, 0x18, 0xe5, 0x33, + 0x12, 0xe4, 0xfd, 0x95, 0xd4, 0xc0, 0x1e, 0x7a, 0x17, 0x80, 0xdf, 0x96, 0x70, 0x31, 0xef, 0x3b, + 0x48, 0x09, 0xab, 0x21, 0x78, 0xf4, 0x34, 0x64, 0xba, 0x8e, 0xdd, 0xb5, 0x5d, 0x7e, 0xf1, 0x75, + 0x14, 0xae, 0x0f, 0x8d, 0x1e, 0x05, 0x44, 0x03, 0x02, 0xed, 0x96, 0xed, 0x99, 0xd6, 0xae, 0xd6, + 0xb5, 0x6f, 0xf3, 0xf7, 0x04, 0x92, 0xaa, 0x4c, 0x6b, 0x6e, 0xd0, 0x8a, 0x4d, 0x52, 0xae, 0x7c, + 0x5a, 0x82, 0xac, 0x4f, 0x85, 0xf8, 0x90, 0x7a, 0xab, 0xe5, 0x60, 0xd7, 0xe5, 0xae, 0x80, 0xf8, + 0x44, 0xef, 0x82, 0x49, 0xae, 0x14, 0xfc, 0x6b, 0xd5, 0x71, 0xde, 0xb2, 0x88, 0xce, 0xb8, 0xbf, + 0x9c, 0x66, 0x3a, 0x03, 0x9d, 0x86, 0x7c, 0x4c, 0x6f, 0x72, 0xb7, 0x82, 0x8e, 0xd0, 0xe7, 0x8a, + 0xf8, 0x10, 0xb4, 0xae, 0x63, 0xda, 0x8e, 0xe9, 0xed, 0x53, 0xd3, 0x93, 0x54, 0x65, 0x51, 0xb1, + 0xc9, 0xcb, 0x95, 0x36, 0x94, 0x1a, 0x66, 0xa7, 0x4b, 0x3d, 0x3c, 0xde, 0xf5, 0x2b, 0x41, 0x07, + 0xa5, 0x31, 0x3a, 0x38, 0xb4, 0x6b, 0x89, 0x81, 0xae, 0x9d, 0xff, 0x4d, 0x89, 0xdb, 0x86, 0xfa, + 0xf2, 0xd5, 0xb6, 0xbe, 0x8b, 0x2e, 0xc2, 0xd1, 0xea, 0xea, 0xc6, 0xd2, 0x8b, 0x5a, 0x7d, 0x59, + 0xbb, 0xba, 0x5a, 0x59, 0x09, 0x4e, 0xf1, 0xce, 0x1d, 0x7b, 0xfd, 0xee, 0x02, 0x0a, 0xc1, 0x6e, + 0x59, 0xd4, 0xc5, 0x41, 0x17, 0x60, 0x26, 0x8a, 0x52, 0xa9, 0x36, 0x6a, 0xeb, 0x4d, 0x59, 0x9a, + 0x3b, 0xfa, 0xfa, 0xdd, 0x85, 0xa9, 0x10, 0x46, 0x65, 0xdb, 0xc5, 0x96, 0x37, 0x88, 0xb0, 0xb4, + 0xb1, 0xb6, 0x56, 0x6f, 0xca, 0x89, 0x01, 0x84, 0x25, 0xbb, 0xd3, 0x31, 0x3d, 0xf4, 0x30, 0x4c, + 0x45, 0x11, 0xd6, 0xeb, 0xab, 0x72, 0x72, 0x0e, 0xbd, 0x7e, 0x77, 0xa1, 0x18, 0x82, 0x5e, 0x37, + 0xdb, 0x73, 0x99, 0x0f, 0xfe, 0xe8, 0xa9, 0x23, 0x9f, 0xfc, 0xc7, 0xa7, 0xa4, 0xea, 0xea, 0x3b, + 0xb2, 0xf0, 0x7e, 0x20, 0x01, 0xf3, 0xfd, 0x9e, 0x92, 0x67, 0x76, 0xb0, 0xeb, 0xe9, 0x9d, 0xee, + 0x30, 0xa7, 0xfd, 0x59, 0xc8, 0x36, 0x05, 0xcc, 0xa1, 0x63, 0x99, 0xbb, 0x87, 0x74, 0x55, 0x8b, + 0x7e, 0x53, 0xc2, 0x57, 0xbd, 0x34, 0xa6, 0xaf, 0xea, 0x8f, 0xe3, 0x9e, 0x9c, 0xd5, 0xdf, 0x69, + 0xc0, 0x7d, 0x01, 0x13, 0xb7, 0x0d, 0x93, 0x28, 0x11, 0xb6, 0x9a, 0x19, 0x5b, 0x64, 0x5f, 0x66, + 0x49, 0x2d, 0x51, 0x46, 0x07, 0xab, 0x9d, 0xb9, 0x11, 0xe9, 0x85, 0xb9, 0x11, 0xbe, 0xf1, 0xdc, + 0x68, 0x0d, 0x39, 0x44, 0x1d, 0x8e, 0x9a, 0x61, 0xe5, 0x3f, 0x67, 0x61, 0x52, 0xc5, 0xef, 0xed, + 0x61, 0xd7, 0x43, 0x4f, 0x40, 0x0a, 0x1b, 0x7b, 0xf6, 0xe0, 0xca, 0xe4, 0xa3, 0x5c, 0xac, 0x19, + 0x7b, 0x36, 0x07, 0xbe, 0x76, 0x44, 0xa5, 0xc0, 0xe8, 0x0a, 0x4c, 0xec, 0xb4, 0x7b, 0xee, 0x1e, + 0x57, 0x38, 0xa7, 0x06, 0xb1, 0xae, 0x92, 0xea, 0x00, 0x8d, 0x81, 0x93, 0xc6, 0xe8, 0x73, 0x5a, + 0xc9, 0x61, 0x8d, 0xd1, 0x57, 0xb4, 0x82, 0xc6, 0x08, 0x30, 0x5a, 0x02, 0x30, 0x2d, 0xd3, 0xd3, + 0x8c, 0x3d, 0xdd, 0xb4, 0xb8, 0xe7, 0xaa, 0xc4, 0xa1, 0x9a, 0xde, 0x12, 0x01, 0x09, 0xf0, 0xb3, + 0xa6, 0x28, 0x23, 0x3d, 0x7e, 0x6f, 0x0f, 0x3b, 0xc2, 0x7b, 0x8d, 0xe9, 0xf1, 0xbb, 0x49, 0x75, + 0xa8, 0xc7, 0x14, 0x9c, 0x78, 0xfb, 0xec, 0xaa, 0xb7, 0x77, 0x87, 0x3f, 0x60, 0xb2, 0x30, 0x88, + 0x4a, 0x6f, 0x7a, 0x37, 0xef, 0x04, 0xc8, 0x93, 0x06, 0x2b, 0x41, 0xcf, 0x40, 0xda, 0xa0, 0x4a, + 0x80, 0x5e, 0xc0, 0xcc, 0x5d, 0x9a, 0x8f, 0x41, 0xa6, 0xf5, 0x01, 0x2e, 0x47, 0x40, 0x1b, 0x50, + 0x6c, 0x9b, 0xae, 0xa7, 0xb9, 0x96, 0xde, 0x75, 0xf7, 0x6c, 0xcf, 0xa5, 0x6f, 0x88, 0xe5, 0x2e, + 0x3d, 0x34, 0x48, 0x62, 0xd5, 0x74, 0xbd, 0x86, 0x00, 0x0b, 0x28, 0x15, 0xda, 0xe1, 0x72, 0x42, + 0xd0, 0xde, 0xd9, 0xc1, 0x8e, 0x4f, 0x91, 0xbe, 0x3d, 0x16, 0x4b, 0x70, 0x83, 0xc0, 0x09, 0xcc, + 0x10, 0x41, 0x3b, 0x5c, 0x8e, 0xbe, 0x01, 0xa6, 0xdb, 0xb6, 0xde, 0xf2, 0xe9, 0x69, 0xc6, 0x5e, + 0xcf, 0xba, 0x39, 0x5b, 0xa4, 0x54, 0xcf, 0xc7, 0x74, 0xd3, 0xd6, 0x5b, 0x02, 0x79, 0x89, 0x80, + 0x06, 0x94, 0xa7, 0xda, 0xfd, 0x75, 0x48, 0x83, 0x19, 0xbd, 0xdb, 0x6d, 0xef, 0xf7, 0x93, 0x2f, + 0x51, 0xf2, 0x8f, 0x0c, 0x92, 0xaf, 0x10, 0xe8, 0x21, 0xf4, 0x91, 0x3e, 0x50, 0x89, 0xb6, 0x40, + 0xee, 0x3a, 0x98, 0x9e, 0xcc, 0x60, 0x56, 0x4c, 0x6f, 0xd3, 0x3b, 0x92, 0xb9, 0x4b, 0xe7, 0x06, + 0x89, 0x6f, 0x32, 0xc8, 0x4d, 0x0e, 0x18, 0x50, 0x2e, 0x75, 0xa3, 0x35, 0x8c, 0xac, 0x6d, 0x60, + 0x7a, 0x87, 0x9b, 0x93, 0x9d, 0x1a, 0x4e, 0x96, 0x42, 0xc6, 0x92, 0x8d, 0xd4, 0xa0, 0xab, 0x90, + 0x63, 0xef, 0xf6, 0x10, 0xe7, 0x01, 0xd3, 0xbb, 0x95, 0xb9, 0x4b, 0x67, 0x62, 0x96, 0x2b, 0x05, + 0xba, 0x61, 0x7b, 0x38, 0x20, 0x06, 0xd8, 0x2f, 0x44, 0xdb, 0x70, 0x94, 0xde, 0x33, 0xdd, 0xd7, + 0xa2, 0x2e, 0xe2, 0xec, 0x34, 0xa5, 0xf8, 0xe8, 0x20, 0x45, 0xfa, 0xc8, 0xd2, 0xfe, 0x8d, 0xb0, + 0xaf, 0x18, 0x90, 0x9e, 0xbe, 0x35, 0x58, 0x4b, 0x24, 0x6d, 0xc7, 0xb4, 0xf4, 0xb6, 0xf9, 0x1a, + 0x66, 0xf1, 0x14, 0x7d, 0x62, 0x21, 0x56, 0xd2, 0xae, 0x72, 0x38, 0x6a, 0x07, 0x43, 0x92, 0xb6, + 0x13, 0x2e, 0xaf, 0x4e, 0xf2, 0x2c, 0x88, 0x7f, 0x67, 0x78, 0x52, 0xce, 0xb0, 0x7b, 0xc2, 0xd7, + 0x53, 0x19, 0x90, 0x73, 0xca, 0x59, 0xc8, 0x85, 0xf4, 0x14, 0x31, 0x52, 0xdc, 0xcf, 0xe7, 0xb9, + 0x15, 0xf1, 0xa9, 0x14, 0x21, 0x1f, 0x56, 0x4d, 0xca, 0x87, 0x24, 0xc8, 0x85, 0x94, 0x0e, 0xc1, + 0x14, 0xc1, 0x35, 0xc7, 0x14, 0xa1, 0xf3, 0x19, 0x11, 0xe8, 0x88, 0xfa, 0x04, 0x0d, 0xa3, 0xf2, + 0xb4, 0x90, 0xc7, 0x59, 0x68, 0x1e, 0x72, 0xdd, 0x4b, 0x5d, 0x1f, 0x24, 0x49, 0x41, 0xa0, 0x7b, + 0xa9, 0x2b, 0x00, 0x4e, 0x43, 0x9e, 0x0c, 0x5d, 0x0b, 0x47, 0xf0, 0x59, 0x35, 0x47, 0xca, 0x38, + 0x88, 0xf2, 0xeb, 0x09, 0x90, 0xfb, 0x95, 0x19, 0x7a, 0x1a, 0x52, 0x44, 0x8b, 0x73, 0x35, 0x3d, + 0x37, 0x10, 0x23, 0xf8, 0x56, 0x93, 0x45, 0x9b, 0x1f, 0x22, 0xb1, 0x0e, 0xc5, 0x40, 0x27, 0x88, + 0x06, 0xd3, 0x4d, 0x4b, 0x33, 0x5b, 0xe2, 0x9d, 0x4a, 0xfa, 0x5d, 0x6f, 0x91, 0x68, 0xd6, 0x10, + 0x39, 0x11, 0x8d, 0xd9, 0x9e, 0x03, 0x52, 0x12, 0x7d, 0xe9, 0x13, 0xb5, 0x64, 0xf4, 0xe5, 0x53, + 0x56, 0x22, 0x6e, 0x35, 0x7b, 0xfd, 0xe6, 0x74, 0x8c, 0x3c, 0x09, 0x98, 0xad, 0x6e, 0x4b, 0xf7, + 0x30, 0xf7, 0x47, 0xc3, 0x1e, 0xf6, 0x43, 0x50, 0xd2, 0xbb, 0x5d, 0xcd, 0xf5, 0x74, 0x0f, 0xf3, + 0xd8, 0x73, 0x82, 0xfa, 0xbc, 0x05, 0xbd, 0xdb, 0xa5, 0xef, 0x7c, 0xb1, 0xd8, 0xf3, 0x41, 0x28, + 0x12, 0x0d, 0x6f, 0xea, 0x6d, 0x11, 0xd8, 0xa4, 0x59, 0x88, 0xca, 0x4b, 0x79, 0x70, 0xd4, 0x82, + 0x7c, 0x58, 0xb9, 0xfb, 0xa9, 0x67, 0x29, 0x48, 0x3d, 0x93, 0x32, 0x7a, 0xf1, 0x84, 0x71, 0x48, + 0x5c, 0xd6, 0x49, 0x73, 0xb2, 0xcc, 0x29, 0xe6, 0x5f, 0xc4, 0xd1, 0xe9, 0x3a, 0xf6, 0x2d, 0x76, + 0x99, 0x2a, 0xa3, 0xb2, 0x0f, 0xe5, 0x65, 0x28, 0x46, 0xed, 0x00, 0x2a, 0x42, 0xc2, 0xbb, 0xc3, + 0x5b, 0x49, 0x78, 0x77, 0xd0, 0xc5, 0xd0, 0x0b, 0x69, 0xc5, 0x38, 0xeb, 0xc7, 0xf1, 0x83, 0xa7, + 0xbd, 0xae, 0xa7, 0x32, 0x09, 0x39, 0xa9, 0x94, 0xa0, 0x10, 0xb1, 0x12, 0xca, 0x31, 0x98, 0x89, + 0xd3, 0xf9, 0x8a, 0x09, 0x33, 0x71, 0xaa, 0x1b, 0x5d, 0x81, 0x8c, 0xaf, 0xf4, 0x85, 0x04, 0x0d, + 0xb4, 0xee, 0x23, 0xf9, 0xb0, 0x44, 0x76, 0xc8, 0x44, 0xd0, 0x1d, 0x8a, 0x04, 0x8f, 0x3a, 0xba, + 0xdd, 0x6b, 0xba, 0xbb, 0xa7, 0x7c, 0x33, 0xcc, 0x0e, 0xd3, 0xe7, 0x21, 0xc6, 0xb1, 0x54, 0x83, + 0x60, 0xdc, 0x31, 0x48, 0xf3, 0xd7, 0x16, 0x12, 0x34, 0x73, 0xca, 0xbf, 0x08, 0x43, 0x99, 0x6e, + 0x4f, 0xb2, 0x84, 0x2a, 0xfd, 0x50, 0x34, 0x38, 0x31, 0x54, 0xa5, 0x07, 0x5b, 0x2a, 0x3c, 0x07, + 0xcb, 0xb6, 0x54, 0x7c, 0x42, 0xac, 0xb3, 0xec, 0x83, 0xbe, 0xc2, 0x89, 0xad, 0x16, 0x0f, 0x6e, + 0xb2, 0x2a, 0xff, 0x52, 0x3e, 0x92, 0x84, 0x63, 0xf1, 0x7a, 0x1d, 0x2d, 0x40, 0xbe, 0xa3, 0xdf, + 0xd1, 0xbc, 0x68, 0xea, 0x03, 0x3a, 0xfa, 0x9d, 0x26, 0xcf, 0x7b, 0xc8, 0x90, 0xf4, 0xee, 0xb8, + 0xf4, 0x22, 0x57, 0x5e, 0x25, 0x7f, 0xa2, 0x1b, 0x30, 0xd5, 0xb6, 0x0d, 0xbd, 0xad, 0xb5, 0x75, + 0xd7, 0xd3, 0xb8, 0xd9, 0x67, 0xcb, 0xe9, 0x81, 0x61, 0x7a, 0x9a, 0x5d, 0xb7, 0x32, 0x3d, 0xa2, + 0x82, 0xf8, 0x42, 0x28, 0x51, 0x22, 0xab, 0xba, 0xeb, 0xf1, 0xf0, 0xa1, 0x06, 0xb9, 0x8e, 0xe9, + 0x6e, 0xe3, 0x3d, 0xfd, 0x96, 0x69, 0x3b, 0x7c, 0x5d, 0xc5, 0x48, 0xcf, 0x5a, 0x00, 0xc4, 0x49, + 0x85, 0xf1, 0x42, 0x93, 0x32, 0x11, 0x91, 0x66, 0xa1, 0x59, 0xd2, 0x87, 0xd6, 0x2c, 0x8f, 0xc3, + 0x8c, 0x85, 0xef, 0xd0, 0xbb, 0x82, 0x7c, 0xe5, 0x32, 0x49, 0x61, 0x57, 0xfd, 0x10, 0xa9, 0xf3, + 0xd7, 0xba, 0x4b, 0x77, 0xb5, 0x1e, 0x06, 0x3f, 0x60, 0xd4, 0x44, 0x34, 0x9b, 0xa1, 0xd0, 0x25, + 0x51, 0x5e, 0x61, 0xc5, 0xca, 0xeb, 0x74, 0x72, 0xe2, 0xac, 0xa3, 0x60, 0xbd, 0x14, 0xb0, 0xbe, + 0x09, 0x33, 0x1c, 0xbf, 0x15, 0xe1, 0xfe, 0x40, 0x78, 0x1e, 0x75, 0xba, 0x42, 0x5c, 0x47, 0x02, + 0x7f, 0x38, 0xe3, 0x93, 0xf7, 0xc8, 0x78, 0x04, 0x29, 0xca, 0x96, 0x14, 0x53, 0x37, 0xe4, 0xef, + 0xff, 0xd7, 0x26, 0xe3, 0xfd, 0x49, 0x98, 0x1a, 0x70, 0x2c, 0xfc, 0x81, 0x49, 0xb1, 0x03, 0x4b, + 0xc4, 0x0e, 0x2c, 0x79, 0xe8, 0x81, 0xf1, 0xd9, 0x4e, 0x8d, 0x9e, 0xed, 0x89, 0xb7, 0x73, 0xb6, + 0xd3, 0xf7, 0x38, 0xdb, 0xef, 0xe8, 0x3c, 0x7c, 0x4c, 0x82, 0xb9, 0xe1, 0xee, 0x58, 0xec, 0x84, + 0x3c, 0x02, 0x53, 0x7e, 0x57, 0x7c, 0xf2, 0x4c, 0x3d, 0xca, 0x7e, 0x05, 0xa7, 0x3f, 0xd4, 0xe2, + 0x3d, 0x08, 0xc5, 0x3e, 0x6f, 0x91, 0x09, 0x73, 0x21, 0x92, 0x41, 0x54, 0x3e, 0x90, 0x84, 0x99, + 0x38, 0x87, 0x2e, 0x66, 0xc5, 0xaa, 0x30, 0xdd, 0xc2, 0x86, 0xd9, 0xba, 0xe7, 0x05, 0x3b, 0xc5, + 0xd1, 0xff, 0xff, 0x7a, 0x8d, 0x91, 0x93, 0x1f, 0x03, 0xc8, 0xa8, 0xd8, 0xed, 0x12, 0x07, 0x8d, + 0xbd, 0xf6, 0x6c, 0xe0, 0xae, 0x17, 0x64, 0xda, 0x63, 0xe3, 0x06, 0x0e, 0x22, 0xf0, 0x48, 0xfc, + 0xec, 0xe3, 0xa1, 0x27, 0x79, 0x9a, 0x60, 0x68, 0xc0, 0xcf, 0xdc, 0x6f, 0x1f, 0x95, 0xe5, 0x09, + 0x9e, 0x12, 0x79, 0x82, 0xe4, 0xb0, 0xe8, 0x97, 0x3b, 0xe3, 0x3e, 0x1e, 0x4f, 0x14, 0x3c, 0xc9, + 0x13, 0x05, 0xa9, 0x61, 0xcd, 0x31, 0x9f, 0x3d, 0x68, 0xce, 0x64, 0x17, 0xb9, 0xc3, 0x99, 0x82, + 0xf4, 0xb0, 0xa1, 0x86, 0x9c, 0xeb, 0x60, 0xa8, 0x41, 0xaa, 0xe0, 0x29, 0x91, 0x2a, 0x98, 0x1c, + 0xd6, 0x69, 0xee, 0x4d, 0x06, 0x9d, 0x66, 0xb9, 0x82, 0xe7, 0x43, 0xb9, 0x82, 0x6c, 0xff, 0xce, + 0xe0, 0x40, 0xae, 0xc0, 0xc7, 0xf6, 0x93, 0x05, 0x65, 0x3f, 0x59, 0x90, 0x1f, 0x9a, 0x69, 0xe0, + 0x6e, 0xa0, 0x8f, 0x2c, 0xb2, 0x05, 0x9b, 0x03, 0xd9, 0x02, 0x16, 0xdc, 0x9f, 0x1d, 0x99, 0x2d, + 0xf0, 0x49, 0xf5, 0xa5, 0x0b, 0x36, 0x07, 0xd2, 0x05, 0xc5, 0x61, 0x14, 0xfb, 0x7c, 0xce, 0x80, + 0x62, 0x34, 0x5f, 0xf0, 0x8d, 0xf1, 0xf9, 0x82, 0xa1, 0x01, 0x7d, 0x8c, 0x7f, 0xe9, 0x93, 0x8e, + 0x49, 0x18, 0x7c, 0xf3, 0x90, 0x84, 0x81, 0x3c, 0x2c, 0xb0, 0x8d, 0xf3, 0x2e, 0xfd, 0x06, 0xe2, + 0x32, 0x06, 0x37, 0x62, 0x32, 0x06, 0x2c, 0xb4, 0x7f, 0x78, 0x8c, 0x8c, 0x81, 0x4f, 0x7a, 0x20, + 0x65, 0x70, 0x23, 0x26, 0x65, 0x80, 0x86, 0xd3, 0xed, 0x73, 0x8a, 0xc2, 0x74, 0xa3, 0x39, 0x83, + 0x95, 0x68, 0xce, 0x60, 0xfa, 0x60, 0x5f, 0x94, 0x99, 0x76, 0x9f, 0x5a, 0x38, 0x69, 0x60, 0x0c, + 0x4b, 0x1a, 0xb0, 0xb8, 0xfe, 0xb1, 0x31, 0x93, 0x06, 0x3e, 0xed, 0xd8, 0xac, 0xc1, 0xe6, 0x40, + 0xd6, 0xe0, 0xe8, 0x30, 0x81, 0xeb, 0x33, 0x32, 0x81, 0xc0, 0x0d, 0x4d, 0x1b, 0xb0, 0x47, 0xc6, + 0xd8, 0xf3, 0x62, 0x20, 0xe7, 0xae, 0xa7, 0x32, 0x39, 0x39, 0xaf, 0x3c, 0x4c, 0xdc, 0x9a, 0x3e, + 0xbd, 0x47, 0x82, 0x08, 0xec, 0x38, 0xb6, 0x23, 0x8e, 0x65, 0xd0, 0x0f, 0xe5, 0x1c, 0xe4, 0xc3, + 0x2a, 0xee, 0x80, 0x14, 0x43, 0x09, 0x0a, 0x11, 0xad, 0xa6, 0xfc, 0x82, 0x04, 0xf9, 0xb0, 0xbe, + 0x8a, 0x04, 0xa0, 0x59, 0x1e, 0x80, 0x86, 0x12, 0x0f, 0x89, 0x68, 0xe2, 0x61, 0x1e, 0x72, 0x24, + 0x08, 0xeb, 0xcb, 0x29, 0xe8, 0x5d, 0x3f, 0xa7, 0x70, 0x1e, 0xa6, 0xa8, 0x0d, 0x65, 0xe9, 0x09, + 0x6e, 0xa7, 0xd8, 0xfe, 0x4c, 0x89, 0x54, 0x50, 0x66, 0xf0, 0x9d, 0xc7, 0xc7, 0x60, 0x3a, 0x04, + 0xeb, 0x07, 0x77, 0x2c, 0xbc, 0x96, 0x7d, 0xe8, 0x0a, 0x8f, 0xf2, 0x7e, 0x59, 0x82, 0xa9, 0x01, + 0x75, 0x19, 0x9b, 0x37, 0x90, 0xde, 0xae, 0xbc, 0x41, 0xe2, 0xde, 0xf3, 0x06, 0xe1, 0x70, 0x35, + 0x19, 0x0d, 0x57, 0xff, 0x52, 0x82, 0x42, 0x44, 0x6d, 0x93, 0x49, 0x30, 0xec, 0x96, 0x38, 0xc4, + 0x43, 0xff, 0x26, 0x7e, 0x4a, 0xdb, 0xde, 0xe5, 0x61, 0x22, 0xf9, 0x93, 0x40, 0xf9, 0x86, 0x28, + 0xcb, 0xcd, 0x8c, 0x1f, 0x7b, 0x4e, 0x84, 0x8f, 0xf3, 0xf1, 0x23, 0x6e, 0xe9, 0xe0, 0x88, 0x9b, + 0x7f, 0x76, 0x67, 0x32, 0x74, 0x76, 0x07, 0x3d, 0x03, 0x59, 0xba, 0x0b, 0xa0, 0xd9, 0xdd, 0xe0, + 0x87, 0x29, 0x86, 0x1f, 0x6f, 0x73, 0xe9, 0xfe, 0x21, 0x3b, 0x13, 0x17, 0x78, 0x21, 0xd9, 0x88, + 0x17, 0x72, 0x1f, 0x64, 0x49, 0xf7, 0xd9, 0xe3, 0x8e, 0xc0, 0x0f, 0xd3, 0x8a, 0x02, 0xe5, 0x27, + 0x13, 0x50, 0xea, 0xb3, 0x3a, 0xb1, 0x83, 0x17, 0x52, 0x99, 0x08, 0xa5, 0x45, 0xc6, 0x63, 0xc8, + 0x29, 0x80, 0x5d, 0xdd, 0xd5, 0x6e, 0xeb, 0x96, 0xc7, 0xdf, 0x70, 0x4f, 0xaa, 0xa1, 0x12, 0x34, + 0x07, 0x19, 0xf2, 0xd5, 0x73, 0xf9, 0x2b, 0xee, 0x49, 0xd5, 0xff, 0x46, 0x75, 0x48, 0xe3, 0x5b, + 0xf4, 0x39, 0x12, 0xf6, 0xa8, 0xcf, 0xf1, 0x18, 0xf5, 0x44, 0xea, 0xab, 0xb3, 0x64, 0xba, 0xff, + 0xf0, 0xcd, 0x79, 0x99, 0x81, 0x3f, 0xea, 0x3f, 0xbf, 0xa0, 0x72, 0x02, 0x51, 0x36, 0x64, 0xfa, + 0xd8, 0x40, 0xd3, 0x85, 0x79, 0x11, 0xfb, 0x13, 0xa6, 0xb2, 0x0d, 0x4b, 0xb5, 0xd0, 0xc1, 0x9d, + 0xae, 0x6d, 0xb7, 0x35, 0xb6, 0xce, 0x2b, 0x50, 0x8c, 0x1a, 0x59, 0xf6, 0xf2, 0xb2, 0xa7, 0x9b, + 0x96, 0x16, 0xf1, 0x8d, 0xf3, 0xac, 0x90, 0xad, 0xab, 0xeb, 0xa9, 0x8c, 0x24, 0x27, 0x78, 0xba, + 0xe6, 0xdd, 0x70, 0x34, 0xd6, 0xc6, 0xa2, 0xa7, 0x21, 0x1b, 0xd8, 0x67, 0xb6, 0xed, 0x7c, 0x50, + 0x1e, 0x26, 0x00, 0x56, 0x6e, 0xc0, 0xd1, 0x58, 0x23, 0x8b, 0x9e, 0x83, 0xb4, 0x83, 0xdd, 0x5e, + 0xdb, 0xe3, 0xcf, 0x22, 0x3e, 0x38, 0xda, 0x3a, 0xf7, 0xda, 0x9e, 0xca, 0x91, 0x94, 0x8b, 0x70, + 0x62, 0xa8, 0x95, 0x0d, 0xb2, 0x29, 0x52, 0x28, 0x9b, 0xa2, 0xfc, 0xb4, 0x04, 0x73, 0xc3, 0x2d, + 0x27, 0xaa, 0xf6, 0x75, 0xe8, 0xfc, 0x98, 0x76, 0x37, 0xd4, 0x2b, 0x12, 0x6e, 0x38, 0x78, 0x07, + 0x7b, 0xc6, 0x1e, 0x33, 0xe1, 0x4c, 0x29, 0x14, 0xd4, 0x02, 0x2f, 0xa5, 0x38, 0x2e, 0x03, 0x7b, + 0x15, 0x1b, 0x9e, 0xc6, 0x26, 0xd5, 0xe5, 0x3f, 0xb5, 0x53, 0x60, 0xa5, 0x0d, 0x56, 0xa8, 0x3c, + 0x02, 0xc7, 0x87, 0xd8, 0xe2, 0xc1, 0xb8, 0x44, 0x79, 0x85, 0x00, 0xc7, 0x1a, 0x58, 0xf4, 0x02, + 0xa4, 0x5d, 0x4f, 0xf7, 0x7a, 0x2e, 0x1f, 0xd9, 0xd9, 0x91, 0xb6, 0xb9, 0x41, 0xc1, 0x55, 0x8e, + 0xa6, 0x3c, 0x0b, 0x68, 0xd0, 0xd2, 0xc6, 0xc4, 0x56, 0x52, 0x5c, 0x6c, 0xb5, 0x0d, 0x27, 0x0f, + 0xb0, 0xa9, 0x68, 0xa9, 0xaf, 0x73, 0x8f, 0x8c, 0x65, 0x92, 0xfb, 0x3a, 0xf8, 0xc7, 0x09, 0x38, + 0x1a, 0x6b, 0x5a, 0x43, 0xab, 0x54, 0x7a, 0xab, 0xab, 0xf4, 0x39, 0x00, 0xef, 0x8e, 0xc6, 0x66, + 0x5a, 0x68, 0xfb, 0xb8, 0x78, 0xe2, 0x0e, 0x36, 0xa8, 0xc2, 0x22, 0x82, 0x91, 0xf5, 0xf8, 0x5f, + 0x24, 0xf8, 0x0f, 0xc5, 0xb3, 0x3d, 0x6a, 0x09, 0x5c, 0x1e, 0xea, 0x8d, 0x6d, 0x33, 0x82, 0xc0, + 0x97, 0x15, 0xbb, 0xe8, 0x15, 0x38, 0xde, 0x67, 0xd1, 0x7c, 0xda, 0xa9, 0xb1, 0x0d, 0xdb, 0xd1, + 0xa8, 0x61, 0x13, 0xb4, 0xc3, 0x56, 0x69, 0x22, 0x6a, 0x95, 0x5e, 0x01, 0x08, 0x02, 0x5b, 0xb2, + 0xde, 0x1c, 0xbb, 0x67, 0xb5, 0xc4, 0xe1, 0x53, 0xfa, 0x81, 0xae, 0xc0, 0x04, 0x91, 0x04, 0xc1, + 0xaa, 0x18, 0x85, 0x41, 0xa6, 0x34, 0x14, 0x19, 0x33, 0x70, 0xe5, 0x55, 0x21, 0x6d, 0xe1, 0x1c, + 0xe3, 0x90, 0x36, 0x9e, 0x8f, 0xb6, 0xa1, 0x0c, 0x4f, 0x57, 0xc6, 0xb7, 0xf5, 0x77, 0x60, 0x82, + 0x4e, 0x7f, 0xec, 0xd9, 0xef, 0x6f, 0x02, 0xd0, 0x3d, 0xcf, 0x31, 0xb7, 0x7b, 0x41, 0x0b, 0x0b, + 0x43, 0xe4, 0xa7, 0x22, 0x00, 0xab, 0xf7, 0x71, 0x41, 0x9a, 0x09, 0x70, 0x43, 0xc2, 0x14, 0xa2, + 0xa8, 0xac, 0x43, 0x31, 0x8a, 0x1b, 0x7f, 0x98, 0x5d, 0xfc, 0x2a, 0x40, 0x70, 0xd4, 0x36, 0x30, + 0xe4, 0xfc, 0xb6, 0x10, 0xfd, 0x50, 0xbe, 0x25, 0x01, 0xf9, 0xb0, 0xf4, 0xfd, 0x2d, 0x34, 0x96, + 0xca, 0x07, 0x24, 0xc8, 0xf8, 0xe3, 0x8f, 0xa6, 0xf3, 0x23, 0xfb, 0x20, 0xc1, 0xb5, 0x06, 0x3f, + 0x07, 0xcf, 0x76, 0x3d, 0x92, 0xfe, 0xae, 0xc7, 0xbb, 0x7c, 0x83, 0x30, 0x34, 0x98, 0x0f, 0x73, + 0x5b, 0x1c, 0x4f, 0xe2, 0x06, 0xea, 0xd9, 0xf1, 0xce, 0x40, 0xcd, 0xc0, 0x44, 0xf8, 0xf8, 0x12, + 0xfb, 0x50, 0x70, 0xe8, 0x04, 0x25, 0x5b, 0x8d, 0xe1, 0xc3, 0x52, 0xd2, 0xe1, 0x0f, 0x4b, 0xf9, + 0xcd, 0x24, 0xc2, 0xcd, 0xfc, 0x23, 0x09, 0x32, 0x62, 0x5d, 0xa0, 0x17, 0xc2, 0xe7, 0x7b, 0xc5, + 0x61, 0xc1, 0xe1, 0x7a, 0x89, 0x37, 0x10, 0x3a, 0xde, 0x5b, 0x15, 0xfb, 0x8c, 0x66, 0x4b, 0xdb, + 0x69, 0xeb, 0xbb, 0x7c, 0xbb, 0x68, 0xe8, 0xe9, 0x64, 0x76, 0x78, 0x88, 0x1f, 0xb8, 0xac, 0xb7, + 0xc8, 0x07, 0xf7, 0x43, 0xfe, 0x5c, 0x02, 0xb9, 0x7f, 0xdd, 0xbe, 0xf5, 0xfe, 0x0d, 0xda, 0xab, + 0x64, 0x8c, 0xbd, 0x42, 0x17, 0x60, 0x3a, 0xf8, 0x61, 0x2e, 0xd7, 0xdc, 0xb5, 0xd8, 0xe1, 0x5f, + 0x96, 0x54, 0x43, 0x7e, 0x55, 0x43, 0xd4, 0x0c, 0x8e, 0x7b, 0xe2, 0x5e, 0xc7, 0xfd, 0xfe, 0x04, + 0xe4, 0x42, 0x39, 0x3e, 0x74, 0x39, 0xa4, 0x94, 0x8a, 0x71, 0x56, 0x22, 0x04, 0x1c, 0xfa, 0x59, + 0x9d, 0x08, 0xa7, 0x12, 0xf7, 0xc0, 0xa9, 0x61, 0xd9, 0x54, 0x91, 0x34, 0x4c, 0x1d, 0x3a, 0x69, + 0x18, 0x7f, 0x80, 0x70, 0x62, 0xc8, 0x01, 0xc2, 0xbf, 0x27, 0x41, 0xc6, 0x4f, 0xbe, 0x1c, 0x76, + 0x4f, 0xee, 0x18, 0xa4, 0xb9, 0xef, 0xc5, 0x36, 0xe5, 0xf8, 0x57, 0x6c, 0x76, 0x74, 0x0e, 0x32, + 0xe2, 0x95, 0x79, 0x6e, 0xe1, 0xfc, 0xef, 0xf3, 0xdb, 0x90, 0x0b, 0x6d, 0x6b, 0xa2, 0x13, 0x70, + 0x74, 0xe9, 0x5a, 0x6d, 0xe9, 0x45, 0xad, 0xf9, 0x52, 0xff, 0xdb, 0xc2, 0x03, 0x55, 0x6a, 0x8d, + 0x7e, 0xcb, 0x12, 0x3a, 0x0e, 0xd3, 0xd1, 0x2a, 0x56, 0x91, 0x98, 0x4b, 0x7d, 0xf0, 0x47, 0x4f, + 0x1d, 0x39, 0xff, 0xe7, 0x12, 0x4c, 0xc7, 0x78, 0xb9, 0xe8, 0x34, 0xdc, 0xbf, 0x71, 0xf5, 0x6a, + 0x4d, 0xd5, 0x1a, 0xeb, 0x95, 0xcd, 0xc6, 0xb5, 0x8d, 0xa6, 0xa6, 0xd6, 0x1a, 0x5b, 0xab, 0xcd, + 0x50, 0xa3, 0x0b, 0x70, 0x5f, 0x3c, 0x48, 0x65, 0x69, 0xa9, 0xb6, 0xd9, 0x64, 0x8f, 0x1b, 0x0f, + 0x81, 0xa8, 0x6e, 0xa8, 0x4d, 0x39, 0x31, 0x9c, 0x84, 0x5a, 0xbb, 0x5e, 0x5b, 0x6a, 0xca, 0x49, + 0x74, 0x16, 0xce, 0x1c, 0x04, 0xa1, 0x5d, 0xdd, 0x50, 0xd7, 0x2a, 0x4d, 0x39, 0x35, 0x12, 0xb0, + 0x51, 0x5b, 0x5f, 0xae, 0xa9, 0xf2, 0x04, 0x1f, 0xf7, 0x1b, 0x09, 0x98, 0x1d, 0xe6, 0x4c, 0x13, + 0x5a, 0x95, 0xcd, 0xcd, 0xd5, 0x97, 0x03, 0x5a, 0x4b, 0xd7, 0xb6, 0xd6, 0x5f, 0x1c, 0x64, 0xc1, + 0x43, 0xa0, 0x1c, 0x04, 0xe8, 0x33, 0xe2, 0x41, 0x38, 0x7d, 0x20, 0x1c, 0x67, 0xc7, 0x08, 0x30, + 0xb5, 0xd6, 0x54, 0x5f, 0x96, 0x93, 0x68, 0x11, 0xce, 0x8f, 0x04, 0xf3, 0xeb, 0xe4, 0x14, 0xba, + 0x00, 0x8f, 0x1c, 0x0c, 0xcf, 0x18, 0x24, 0x10, 0x04, 0x8b, 0x5e, 0x97, 0xe0, 0x68, 0xac, 0x57, + 0x8e, 0xce, 0xc0, 0xfc, 0xa6, 0xba, 0xb1, 0x54, 0x6b, 0x34, 0xb4, 0x4d, 0x75, 0x63, 0x73, 0xa3, + 0x51, 0x59, 0xd5, 0x1a, 0xcd, 0x4a, 0x73, 0xab, 0x11, 0xe2, 0x8d, 0x02, 0xa7, 0x86, 0x01, 0xf9, + 0x7c, 0x39, 0x00, 0x86, 0x4b, 0x80, 0x90, 0xd3, 0xbb, 0x12, 0x9c, 0x18, 0xea, 0x85, 0xa3, 0x73, + 0xf0, 0x00, 0xfd, 0x9d, 0xb2, 0x97, 0xb5, 0x1b, 0x1b, 0xcd, 0xf0, 0x2b, 0xda, 0x03, 0xbd, 0x3a, + 0x0b, 0x67, 0x0e, 0x84, 0xf4, 0xbb, 0x36, 0x0a, 0xb0, 0xaf, 0x7f, 0xdf, 0x26, 0x41, 0xa9, 0x4f, + 0x17, 0xa2, 0xfb, 0x60, 0x76, 0xad, 0xde, 0xa8, 0xd6, 0xae, 0x55, 0x6e, 0xd4, 0x37, 0xd4, 0xfe, + 0x35, 0x7b, 0x06, 0xe6, 0x07, 0x6a, 0x97, 0xb7, 0x36, 0x57, 0xeb, 0x4b, 0x95, 0x66, 0x8d, 0x36, + 0x2a, 0x4b, 0x64, 0x60, 0x03, 0x40, 0xab, 0xf5, 0x95, 0x6b, 0x4d, 0x6d, 0x69, 0xb5, 0x5e, 0x5b, + 0x6f, 0x6a, 0x95, 0x66, 0xb3, 0x12, 0x2c, 0xe7, 0xea, 0x8b, 0x43, 0x8f, 0xbe, 0x5e, 0x1c, 0xff, + 0xe8, 0x2b, 0x3f, 0xc2, 0x19, 0xdc, 0x56, 0x4b, 0xc0, 0xbc, 0x5f, 0xc9, 0x73, 0x69, 0xfd, 0x47, + 0x3c, 0xa7, 0x7d, 0xed, 0xce, 0x01, 0x86, 0xdf, 0xf8, 0x7c, 0x0e, 0x92, 0x95, 0x6e, 0x97, 0x68, + 0x3e, 0xfa, 0x6d, 0xd8, 0x6d, 0xae, 0x57, 0xfd, 0x6f, 0x52, 0xe7, 0xda, 0x3b, 0xde, 0x6d, 0xdd, + 0xf1, 0x7f, 0x79, 0x4d, 0x7c, 0x2b, 0xcf, 0x40, 0xd6, 0x8f, 0x1e, 0xe8, 0xdb, 0xa5, 0xfe, 0x3d, + 0xa4, 0x94, 0xb8, 0x67, 0xc4, 0x2f, 0x6b, 0x24, 0x82, 0xcb, 0x1a, 0xa9, 0x2f, 0xbe, 0x31, 0x2f, + 0x55, 0xd7, 0x87, 0x72, 0xe7, 0xc9, 0xf1, 0xb9, 0x13, 0x30, 0xc0, 0x67, 0xd0, 0xf7, 0xdd, 0x1f, + 0xba, 0x0d, 0xec, 0x9f, 0x38, 0x0d, 0xb3, 0x27, 0xe6, 0x3c, 0xfe, 0xa8, 0x33, 0xae, 0x63, 0x9c, + 0x61, 0x1d, 0x35, 0x2b, 0xf7, 0x7a, 0xc8, 0xf5, 0x19, 0x28, 0x6c, 0xea, 0x8e, 0xd7, 0xc0, 0xde, + 0x35, 0xac, 0xb7, 0xb0, 0x13, 0xbd, 0x9b, 0x5b, 0x10, 0x77, 0x73, 0x85, 0x3d, 0x4b, 0x04, 0xf6, + 0x4c, 0x31, 0x21, 0x45, 0x9f, 0x13, 0x1e, 0x7a, 0xc8, 0x84, 0x1d, 0x0a, 0xe1, 0x87, 0x4c, 0xe8, + 0x07, 0xba, 0x2c, 0x6e, 0xdf, 0x26, 0x47, 0xdc, 0xbe, 0x15, 0x91, 0x13, 0xbb, 0x83, 0xdb, 0x81, + 0x49, 0xee, 0xcd, 0xc4, 0xee, 0xde, 0xae, 0x43, 0xa9, 0xab, 0x3b, 0x1e, 0xfd, 0xb5, 0x92, 0x3d, + 0x3a, 0x0c, 0xee, 0x89, 0xc4, 0x5d, 0x9f, 0x8a, 0x0c, 0x97, 0x37, 0x53, 0xe8, 0x86, 0x0b, 0x95, + 0x2f, 0xa6, 0x20, 0xcd, 0xd9, 0xf1, 0x7c, 0xf4, 0xa4, 0x5b, 0xc4, 0x31, 0x0f, 0xc4, 0x3f, 0x08, + 0x72, 0x39, 0x41, 0x3f, 0x2d, 0xfd, 0x50, 0xff, 0xb9, 0xb2, 0x6a, 0xee, 0xf3, 0x6f, 0xce, 0x4f, + 0xd2, 0x4c, 0x71, 0x7d, 0x39, 0x38, 0x64, 0xf6, 0xf6, 0x7b, 0x41, 0xcb, 0x50, 0x08, 0xe5, 0xb0, + 0xcd, 0x16, 0xdf, 0xf8, 0x9f, 0x1b, 0xee, 0x29, 0x8a, 0x6d, 0x5e, 0x3f, 0xbf, 0x5d, 0x6f, 0xa1, + 0x73, 0x20, 0x87, 0x76, 0x9e, 0x59, 0x78, 0xce, 0x92, 0xb7, 0xc5, 0xb6, 0xbf, 0xa7, 0x4c, 0x37, + 0x5e, 0x4f, 0x42, 0x96, 0xfe, 0x80, 0x4e, 0x68, 0x7f, 0x36, 0x43, 0x0a, 0x68, 0xe5, 0x59, 0x28, + 0xf5, 0x6f, 0xe1, 0xb2, 0x4d, 0xd9, 0xe2, 0xad, 0xe8, 0xf6, 0xed, 0xb0, 0x0d, 0xdf, 0xec, 0xd0, + 0x0d, 0xdf, 0x07, 0xa1, 0x18, 0x24, 0x25, 0x28, 0x2c, 0x30, 0x4f, 0xdb, 0x2f, 0xa5, 0x60, 0xe1, + 0xfc, 0x42, 0x2e, 0x92, 0x5f, 0xf0, 0x77, 0x06, 0x78, 0xb6, 0x85, 0xc1, 0xe4, 0xd9, 0x9e, 0x31, + 0xa9, 0xe0, 0x49, 0x15, 0x0a, 0x7b, 0x06, 0x0a, 0xe2, 0x92, 0x22, 0x83, 0x2b, 0x50, 0xb8, 0xbc, + 0x28, 0x1c, 0xba, 0x07, 0x5d, 0x8c, 0xdf, 0x83, 0x9e, 0x85, 0xd4, 0x32, 0x8f, 0x8a, 0xfb, 0x72, + 0x6c, 0x9f, 0x4d, 0x42, 0x8a, 0x6e, 0x2b, 0x3d, 0x19, 0x71, 0xcc, 0xe3, 0x44, 0x9a, 0x84, 0x07, + 0xb8, 0xb5, 0xe6, 0xee, 0x86, 0xfc, 0xf2, 0x61, 0x47, 0x4c, 0xfc, 0xd4, 0x46, 0x32, 0x9c, 0xda, + 0xb8, 0x0a, 0x19, 0x5f, 0x4e, 0x52, 0x23, 0xe5, 0xa4, 0x44, 0xe4, 0x84, 0x88, 0x31, 0x2f, 0x50, + 0x27, 0x79, 0x78, 0x81, 0xaa, 0x90, 0xf5, 0x35, 0x8c, 0x2f, 0x70, 0xe3, 0xc8, 0x6c, 0x80, 0x16, + 0x7f, 0x16, 0x23, 0x3d, 0xe4, 0x2c, 0x46, 0x58, 0xb0, 0xf8, 0x6f, 0x6f, 0x4e, 0xd2, 0x81, 0x05, + 0x82, 0xc5, 0x7e, 0x7f, 0xf3, 0x3e, 0xc8, 0x06, 0xf1, 0x15, 0x93, 0xbd, 0xa0, 0x80, 0xd4, 0x06, + 0x91, 0x1a, 0x93, 0xb5, 0xd0, 0x8f, 0x38, 0x0f, 0x89, 0xd2, 0x60, 0x58, 0x94, 0xa6, 0xfc, 0x5b, + 0x09, 0xd2, 0xfc, 0xb8, 0xc5, 0x01, 0x69, 0x01, 0x36, 0x0f, 0x89, 0x61, 0xf3, 0x90, 0x7c, 0x4b, + 0xf3, 0x00, 0x7e, 0x3f, 0xc5, 0x21, 0xd3, 0xfb, 0x62, 0x93, 0x73, 0xa4, 0x93, 0x0d, 0x73, 0x57, + 0xec, 0x13, 0x05, 0x58, 0xca, 0x9b, 0x12, 0x31, 0xbf, 0xbc, 0x7e, 0x30, 0xf0, 0x94, 0x0e, 0x1d, + 0x78, 0x1e, 0xee, 0x94, 0x4d, 0x44, 0x94, 0x92, 0xf7, 0x26, 0x4a, 0x91, 0x49, 0x4f, 0xf5, 0x4d, + 0xba, 0xf2, 0x05, 0x89, 0xff, 0x7e, 0xb3, 0x9f, 0xfc, 0xfb, 0x2b, 0x9a, 0xad, 0xaf, 0xe7, 0xf2, + 0xd5, 0xc2, 0x2d, 0x6d, 0x60, 0xda, 0x1e, 0x88, 0xbb, 0x37, 0x1d, 0xe9, 0x75, 0x30, 0x7d, 0x48, + 0x90, 0x69, 0x04, 0xd3, 0xf8, 0x73, 0x09, 0x71, 0x2a, 0x2d, 0x04, 0xff, 0x37, 0x70, 0x3a, 0xa3, + 0x6b, 0x78, 0x62, 0xcc, 0x35, 0x9c, 0x1e, 0xba, 0x86, 0x7f, 0x2e, 0x41, 0xdf, 0xd9, 0x60, 0x67, + 0x04, 0xbe, 0x16, 0x3a, 0xf8, 0x24, 0x64, 0xbb, 0x76, 0x5b, 0x63, 0x35, 0xec, 0x31, 0xfe, 0x4c, + 0xd7, 0x6e, 0xab, 0x03, 0xa2, 0x36, 0xf1, 0x76, 0x29, 0xe8, 0xf4, 0xdb, 0x30, 0x0d, 0x93, 0xfd, + 0xab, 0xca, 0x83, 0x3c, 0xe3, 0x05, 0xf7, 0xa0, 0x2e, 0x12, 0x26, 0x50, 0x9f, 0x4c, 0xea, 0xf7, + 0xf9, 0xfc, 0x7e, 0x33, 0x50, 0x95, 0x03, 0x12, 0x94, 0xc8, 0x49, 0xb7, 0x13, 0x43, 0x35, 0x97, + 0x38, 0xd9, 0xa3, 0x7c, 0x58, 0x02, 0x58, 0x25, 0xcc, 0xa5, 0x23, 0x26, 0xce, 0x8f, 0x4b, 0x3b, + 0xa1, 0x45, 0xda, 0x9e, 0x1f, 0x3a, 0x71, 0xbc, 0x07, 0x79, 0x37, 0xdc, 0xf5, 0x65, 0x28, 0x04, + 0x02, 0xee, 0x62, 0xd1, 0x9d, 0xf9, 0x83, 0x2e, 0xb2, 0x36, 0xb0, 0xa7, 0xe6, 0x6f, 0x85, 0xbe, + 0x94, 0x7f, 0x27, 0x41, 0x96, 0xf6, 0x6a, 0x0d, 0x7b, 0x7a, 0x64, 0x22, 0xa5, 0xb7, 0x30, 0x91, + 0xf7, 0x03, 0x30, 0x3a, 0xae, 0xf9, 0x1a, 0xe6, 0xf2, 0x95, 0xa5, 0x25, 0x0d, 0xf3, 0x35, 0x8c, + 0x9e, 0xf2, 0xb9, 0x9e, 0x1c, 0xc1, 0x75, 0x91, 0xbc, 0xe5, 0xbc, 0x3f, 0x0e, 0x93, 0x56, 0xaf, + 0xa3, 0xb1, 0xc3, 0xa4, 0x54, 0x68, 0xad, 0x5e, 0xa7, 0x79, 0xc7, 0x55, 0x6e, 0xc2, 0x64, 0xf3, + 0x0e, 0x7b, 0xbf, 0xe7, 0x24, 0x64, 0x1d, 0xdb, 0xe6, 0xde, 0x20, 0x73, 0xc4, 0x33, 0xa4, 0x80, + 0x3a, 0x3f, 0x71, 0x39, 0xff, 0x0b, 0xe3, 0xba, 0xfd, 0xdc, 0xe1, 0x3f, 0xff, 0x9b, 0x12, 0x14, + 0x22, 0x2b, 0x0a, 0x3d, 0x0a, 0xc7, 0x1b, 0xf5, 0x95, 0xf5, 0xda, 0xb2, 0xb6, 0xd6, 0x58, 0xe9, + 0x0b, 0xb0, 0xe7, 0x4a, 0xaf, 0xdf, 0x5d, 0xc8, 0xf1, 0xab, 0xaa, 0xc3, 0xa0, 0x37, 0xd5, 0x1a, + 0x8b, 0xb4, 0x19, 0xf4, 0xa6, 0x83, 0x6f, 0xd9, 0x1e, 0xa6, 0xd0, 0x8f, 0xc3, 0x89, 0x18, 0x68, + 0xff, 0xc2, 0xea, 0xd4, 0xeb, 0x77, 0x17, 0x0a, 0x9b, 0x0e, 0x66, 0xa2, 0x46, 0x31, 0x16, 0x61, + 0x76, 0x10, 0x83, 0x65, 0x35, 0xe4, 0x85, 0x39, 0xf9, 0xf5, 0xbb, 0x0b, 0x79, 0xa1, 0x3b, 0x08, + 0xfc, 0x3b, 0x7e, 0x63, 0xf5, 0xa3, 0x59, 0x38, 0xc1, 0xde, 0xb0, 0xd2, 0x58, 0x0c, 0xc8, 0x3e, + 0x78, 0x48, 0x9a, 0x0f, 0x57, 0x8d, 0xfe, 0x71, 0x02, 0xe5, 0x45, 0x98, 0xae, 0x5b, 0x1e, 0x76, + 0x76, 0xf4, 0xf0, 0xcf, 0x0b, 0xc7, 0xfe, 0x60, 0xef, 0x42, 0xe4, 0x95, 0x4d, 0x1e, 0xc1, 0x87, + 0x8b, 0x94, 0x6f, 0x91, 0x40, 0x6e, 0x18, 0x7a, 0x5b, 0x77, 0xde, 0x2a, 0x29, 0xf4, 0x94, 0xf8, + 0x51, 0x0a, 0x7e, 0x41, 0x24, 0x79, 0xae, 0x78, 0x69, 0x76, 0x31, 0x3c, 0xb8, 0x45, 0xd6, 0x12, + 0xd5, 0xc1, 0xec, 0xc7, 0x28, 0xc8, 0x9f, 0xe7, 0x5f, 0x02, 0x08, 0x2a, 0xd0, 0x49, 0x38, 0xde, + 0x58, 0xaa, 0xac, 0x56, 0xfc, 0x3c, 0x4d, 0x63, 0xb3, 0xb6, 0xc4, 0x7e, 0xf9, 0xfe, 0x08, 0x3a, + 0x06, 0x28, 0x5c, 0xe9, 0xff, 0xce, 0xdc, 0x51, 0x98, 0x0a, 0x97, 0xb3, 0x9f, 0x21, 0x4f, 0x94, + 0xaf, 0x41, 0x89, 0xfd, 0x46, 0x32, 0x31, 0x80, 0xb8, 0xa5, 0x99, 0x16, 0x1a, 0xf1, 0x93, 0xc3, + 0xb3, 0xbf, 0xfa, 0x5f, 0xd9, 0x4f, 0x54, 0x14, 0x18, 0x62, 0x85, 0xe0, 0xd5, 0xad, 0x72, 0x13, + 0x66, 0xe8, 0x8d, 0x70, 0xfa, 0xb3, 0x32, 0x9a, 0x29, 0xf8, 0x3f, 0xfa, 0x0d, 0x41, 0x42, 0x2f, + 0x79, 0x2e, 0xab, 0x4e, 0x07, 0xe8, 0xfe, 0xec, 0x95, 0x5f, 0x0c, 0x7e, 0x54, 0xc4, 0xef, 0xe0, + 0x48, 0x8a, 0xbf, 0xc6, 0x7b, 0x28, 0x9e, 0x10, 0x16, 0x5d, 0x5c, 0x85, 0x29, 0xdd, 0x30, 0x70, + 0x37, 0xd2, 0xbf, 0x11, 0xcf, 0xb6, 0x89, 0xd1, 0xca, 0x1c, 0x33, 0xe8, 0xda, 0x53, 0x90, 0x76, + 0xe9, 0xa4, 0x8c, 0x22, 0x21, 0xba, 0xc3, 0xc1, 0xcb, 0x35, 0x28, 0x32, 0x31, 0xf0, 0x47, 0x34, + 0x82, 0xc0, 0x7f, 0xe4, 0x04, 0xf2, 0x14, 0x4d, 0x8c, 0xc6, 0x82, 0xa9, 0x16, 0x36, 0xda, 0xba, + 0x83, 0x43, 0xa3, 0x39, 0xf8, 0xe9, 0xe2, 0x7f, 0xf9, 0xe9, 0xc7, 0xfd, 0x3d, 0xf4, 0x90, 0xd0, + 0xc5, 0x2c, 0x16, 0x55, 0xe6, 0xb4, 0x83, 0xf1, 0x62, 0x28, 0x8a, 0xf6, 0xf8, 0xb8, 0x0f, 0x6e, + 0xec, 0x5f, 0xf1, 0xc6, 0x4e, 0xc5, 0x49, 0x78, 0xa8, 0xa5, 0x02, 0xa7, 0xca, 0x2a, 0xca, 0x55, + 0x28, 0xec, 0x98, 0xed, 0xd0, 0x74, 0x1f, 0xdc, 0xca, 0xbf, 0xfe, 0xf4, 0xe3, 0x6c, 0xa1, 0x11, + 0x24, 0xce, 0x9a, 0x7b, 0xfa, 0xc9, 0x14, 0x4a, 0xfd, 0xd9, 0x70, 0x57, 0x7d, 0xed, 0xf4, 0x89, + 0x24, 0x9c, 0xe2, 0xc0, 0xdb, 0xba, 0x8b, 0x89, 0xe2, 0xc2, 0x9e, 0x7e, 0xf1, 0x82, 0x61, 0x9b, + 0x56, 0x90, 0x54, 0xa4, 0x0a, 0x8b, 0xd4, 0x2f, 0xf2, 0xfa, 0x21, 0x39, 0xad, 0xe1, 0x8a, 0x6e, + 0x6e, 0xf0, 0x67, 0x7b, 0x94, 0x36, 0xa4, 0x96, 0x6c, 0xd3, 0x22, 0x3e, 0x57, 0x0b, 0x5b, 0x76, + 0x47, 0x9c, 0x57, 0xa4, 0x1f, 0xe8, 0x1a, 0xa4, 0xf5, 0x8e, 0xdd, 0xb3, 0xf8, 0xfb, 0x6d, 0xd5, + 0xc7, 0x89, 0x2d, 0xfc, 0xed, 0x37, 0xe7, 0x8f, 0x32, 0xb2, 0x6e, 0xeb, 0xe6, 0xa2, 0x69, 0x5f, + 0xe8, 0xe8, 0xde, 0x1e, 0x99, 0xe4, 0xdf, 0xf8, 0xcc, 0x63, 0xc0, 0xdb, 0xab, 0x5b, 0xde, 0x27, + 0xff, 0xe0, 0x67, 0xce, 0x4b, 0x2a, 0xc7, 0x67, 0x69, 0x47, 0xa5, 0x0b, 0x93, 0xcb, 0xd8, 0x38, + 0xa0, 0xc1, 0x7a, 0x5f, 0x83, 0x17, 0x79, 0x83, 0x27, 0x07, 0x1b, 0x64, 0xbf, 0x23, 0xb8, 0x8c, + 0x8d, 0x50, 0xb3, 0xcb, 0xd8, 0x88, 0xb6, 0x58, 0x5d, 0xfe, 0xad, 0xdf, 0x3b, 0x75, 0xe4, 0x7d, + 0x9f, 0x3f, 0x75, 0x64, 0xe8, 0x94, 0x29, 0xa3, 0x7f, 0xe5, 0xc6, 0x9f, 0xa9, 0xff, 0x2d, 0xc1, + 0x89, 0x7e, 0xf3, 0xa0, 0x5b, 0xfb, 0xc3, 0xde, 0x3c, 0xb8, 0x02, 0xc9, 0x8a, 0xb5, 0x8f, 0x4e, + 0xb0, 0xd7, 0x5c, 0xb5, 0x9e, 0xd3, 0x16, 0xc7, 0x3c, 0xc9, 0xf7, 0x96, 0xd3, 0x8e, 0x1e, 0x29, + 0xf0, 0x5f, 0xe6, 0xfa, 0xee, 0x43, 0x3e, 0x77, 0x90, 0xa9, 0x58, 0xfb, 0xe2, 0xa1, 0x83, 0x47, + 0xc7, 0x7c, 0xe8, 0x40, 0xb7, 0xf6, 0xbb, 0xdb, 0x87, 0x7d, 0xdf, 0xe0, 0x03, 0x97, 0xe1, 0x01, + 0xce, 0x23, 0xd7, 0xd3, 0x6f, 0x9a, 0xd6, 0xae, 0x2f, 0xac, 0xfc, 0x9b, 0xb3, 0xe2, 0x18, 0x9f, + 0x10, 0x51, 0x2a, 0x44, 0x76, 0x50, 0x02, 0xe7, 0x0e, 0x7c, 0x30, 0x61, 0xee, 0xe0, 0x6c, 0xf2, + 0xdc, 0x88, 0x75, 0x73, 0xd0, 0x62, 0x18, 0xb2, 0x7a, 0x86, 0x4e, 0xef, 0xc8, 0xd7, 0xc3, 0x46, + 0x26, 0x93, 0x3f, 0x2c, 0x41, 0xf1, 0x9a, 0xe9, 0x7a, 0xb6, 0x63, 0x1a, 0x7a, 0x9b, 0x6e, 0xa4, + 0xbf, 0x6b, 0x6c, 0xef, 0xbf, 0x9a, 0x25, 0x4b, 0x81, 0x2f, 0xaa, 0x3d, 0xe1, 0x80, 0xa7, 0x6f, + 0xe9, 0x6d, 0xe6, 0x79, 0x87, 0xf5, 0x6e, 0x3f, 0xdb, 0x43, 0xfb, 0xcb, 0x61, 0x2a, 0x0c, 0xb7, + 0x9c, 0x98, 0x95, 0x94, 0xef, 0x4f, 0x40, 0x89, 0x86, 0x0c, 0x2e, 0x3d, 0x10, 0x46, 0x8f, 0x1c, + 0x5d, 0x87, 0x94, 0xa3, 0x7b, 0xdc, 0x09, 0xa9, 0x5e, 0x39, 0xf4, 0x4a, 0x64, 0xad, 0x50, 0x1a, + 0xe8, 0xdd, 0x90, 0xe9, 0xe8, 0x77, 0x34, 0x4a, 0x2f, 0xf1, 0x96, 0xe8, 0x4d, 0x76, 0xf4, 0x3b, + 0xa4, 0x7f, 0xe8, 0x9b, 0xa0, 0x44, 0x48, 0x1a, 0x7b, 0xba, 0xb5, 0x8b, 0x19, 0xe5, 0xe4, 0x5b, + 0xa2, 0x5c, 0xe8, 0xe8, 0x77, 0x96, 0x28, 0x35, 0x42, 0x9f, 0x6b, 0xac, 0x5f, 0x92, 0xf8, 0xe9, + 0x2a, 0xca, 0x18, 0xa4, 0x83, 0x6c, 0xf8, 0x5f, 0xb4, 0x51, 0x71, 0x68, 0xf9, 0xec, 0x30, 0xde, + 0xf7, 0xb1, 0xb5, 0x5a, 0x20, 0xdd, 0xfb, 0xdc, 0x9b, 0xf3, 0x12, 0x6b, 0xb5, 0x64, 0x0c, 0xb0, + 0x3d, 0xc7, 0x4e, 0x8d, 0x69, 0x34, 0xb3, 0x9d, 0x18, 0x19, 0x84, 0x16, 0x44, 0x10, 0xca, 0x08, + 0x02, 0xc3, 0x26, 0xf5, 0x7c, 0x0c, 0x7f, 0x2a, 0x41, 0x6e, 0x39, 0xe4, 0x27, 0xce, 0xc2, 0x64, + 0xc7, 0xb6, 0xcc, 0x9b, 0xd8, 0xf1, 0x4f, 0x9d, 0xb3, 0x4f, 0x34, 0x07, 0x19, 0xf6, 0x0b, 0x90, + 0xde, 0xbe, 0xd8, 0x6d, 0x12, 0xdf, 0x04, 0xeb, 0x36, 0xde, 0x76, 0x4d, 0xc1, 0x67, 0x55, 0x7c, + 0xa2, 0x87, 0x41, 0x76, 0xb1, 0xd1, 0x73, 0x4c, 0x6f, 0x5f, 0x33, 0x6c, 0xcb, 0xd3, 0x0d, 0x8f, + 0x1f, 0x56, 0x2a, 0x89, 0xf2, 0x25, 0x56, 0x4c, 0x88, 0xb4, 0xb0, 0xa7, 0x9b, 0x6d, 0x76, 0x19, + 0x3b, 0xab, 0x8a, 0x4f, 0xb4, 0x12, 0xda, 0xfe, 0x4f, 0xfb, 0xbb, 0x13, 0xb1, 0x1c, 0x15, 0xbf, + 0x37, 0x1f, 0x16, 0x66, 0x1f, 0x99, 0x8f, 0x79, 0x07, 0x32, 0x02, 0x0c, 0x3d, 0x04, 0xa5, 0xae, + 0x63, 0x53, 0xab, 0xdf, 0x35, 0x0d, 0xad, 0xe7, 0x98, 0x7c, 0xdc, 0x05, 0x5e, 0xbc, 0x69, 0x1a, + 0x5b, 0x8e, 0x89, 0x1e, 0x05, 0xe4, 0xda, 0x06, 0xbd, 0x08, 0xae, 0x5b, 0xad, 0x36, 0x51, 0xd8, + 0x26, 0x3b, 0x6b, 0x96, 0x55, 0x65, 0x56, 0x73, 0x8d, 0x56, 0x6c, 0x39, 0xa6, 0xcb, 0xdb, 0xb9, + 0x3b, 0x19, 0x3e, 0x5b, 0xb4, 0x04, 0xb2, 0xdd, 0xc5, 0x4e, 0x24, 0xe3, 0xc3, 0x96, 0xcf, 0xec, + 0x6f, 0x7c, 0xe6, 0xb1, 0x19, 0x3e, 0x1e, 0x9e, 0xf3, 0x61, 0xaf, 0x38, 0xaa, 0x25, 0x81, 0x21, + 0x52, 0x41, 0x2f, 0x47, 0x0e, 0xc6, 0xf7, 0xb6, 0x83, 0x37, 0x99, 0x66, 0x06, 0xa4, 0xa0, 0x62, + 0xed, 0x57, 0x67, 0x7f, 0x2d, 0x20, 0xcd, 0xe3, 0xc5, 0x4d, 0x7a, 0xd2, 0x28, 0x7c, 0x48, 0x9e, + 0x92, 0x41, 0xc7, 0x20, 0xfd, 0xaa, 0x6e, 0xb6, 0xc5, 0xaf, 0xfb, 0xaa, 0xfc, 0x0b, 0x95, 0xfd, + 0x83, 0x9f, 0x29, 0x9a, 0xc1, 0x51, 0x86, 0xb1, 0xbe, 0x6a, 0x5b, 0xad, 0xe8, 0x79, 0x4f, 0xb4, + 0x04, 0x69, 0xcf, 0xbe, 0x89, 0x2d, 0x3e, 0xa3, 0xd5, 0x47, 0x0e, 0xe1, 0x23, 0xa8, 0x1c, 0x15, + 0x7d, 0x03, 0xc8, 0x2d, 0xdc, 0xc6, 0xbb, 0x2c, 0x95, 0xb0, 0xa7, 0x3b, 0x98, 0xe5, 0xb4, 0xef, + 0xc9, 0x03, 0x28, 0xf9, 0xa4, 0x1a, 0x94, 0x12, 0xda, 0x8c, 0x86, 0x4e, 0x93, 0xfe, 0x9d, 0xae, + 0xd8, 0x31, 0x86, 0x96, 0x4a, 0x58, 0xc2, 0x22, 0xa1, 0xd6, 0xc3, 0x20, 0xf7, 0xac, 0x6d, 0xdb, + 0xa2, 0x3f, 0x8a, 0xc9, 0x93, 0x58, 0x19, 0x76, 0x59, 0xc2, 0x2f, 0xe7, 0x97, 0x25, 0x36, 0xa1, + 0x18, 0x80, 0xd2, 0x25, 0x9d, 0x3d, 0xec, 0x92, 0x2e, 0xf8, 0x04, 0x08, 0x08, 0x5a, 0x03, 0x08, + 0x94, 0x06, 0x4d, 0xb3, 0xe7, 0x86, 0xcf, 0x58, 0xa0, 0x7e, 0xc2, 0x83, 0x09, 0x11, 0x40, 0x16, + 0x4c, 0x77, 0x4c, 0x4b, 0x73, 0x71, 0x7b, 0x47, 0xe3, 0x9c, 0x23, 0x74, 0x73, 0x94, 0xfd, 0xcf, + 0x1f, 0x62, 0x36, 0x7f, 0xfb, 0x33, 0x8f, 0x95, 0x02, 0xd7, 0x69, 0xe1, 0xf1, 0xc5, 0x27, 0x9f, + 0x52, 0xa7, 0x3a, 0xa6, 0xd5, 0xc0, 0xed, 0x9d, 0x65, 0x9f, 0x30, 0x7a, 0x17, 0x9c, 0x0c, 0x18, + 0x62, 0x5b, 0xda, 0x9e, 0xdd, 0x6e, 0x69, 0x0e, 0xde, 0xd1, 0x0c, 0xea, 0xf8, 0xe5, 0x29, 0x1b, + 0x8f, 0xfb, 0x20, 0x1b, 0xd6, 0x35, 0xbb, 0xdd, 0x52, 0xf1, 0xce, 0x12, 0xa9, 0x46, 0x67, 0x20, + 0xe0, 0x86, 0x66, 0xb6, 0xdc, 0xd9, 0xc2, 0x42, 0xf2, 0x5c, 0x4a, 0xcd, 0xfb, 0x85, 0xf5, 0x96, + 0x5b, 0xce, 0x7c, 0xf0, 0x8d, 0xf9, 0x23, 0x5f, 0x7c, 0x63, 0xfe, 0x88, 0x72, 0x95, 0xbe, 0xda, + 0xc6, 0x97, 0x16, 0x76, 0xd1, 0x15, 0xc8, 0xea, 0xe2, 0x83, 0x3d, 0x7c, 0x78, 0xc0, 0xd2, 0x0c, + 0x40, 0x95, 0x4f, 0x49, 0x90, 0x5e, 0xbe, 0xb1, 0xa9, 0x9b, 0x0e, 0xaa, 0x91, 0xc0, 0x48, 0xc8, + 0xea, 0xb8, 0xab, 0x3c, 0x10, 0x6f, 0xb1, 0xcc, 0xd7, 0x87, 0xa5, 0x87, 0xb3, 0xd5, 0xd3, 0xbf, + 0xf1, 0x99, 0xc7, 0xee, 0xe7, 0x64, 0x6e, 0xf4, 0x65, 0x8a, 0x05, 0xbd, 0xfe, 0x0c, 0x72, 0x68, + 0xcc, 0xd7, 0x61, 0x92, 0x75, 0xd5, 0x45, 0x2f, 0xc0, 0x44, 0x97, 0xfc, 0xc1, 0x4f, 0x5c, 0x9f, + 0x1a, 0x2a, 0xf3, 0x14, 0x3e, 0x2c, 0x21, 0x0c, 0x4f, 0xf9, 0x8e, 0x04, 0xc0, 0xf2, 0x8d, 0x1b, + 0x4d, 0xc7, 0xec, 0xb6, 0xb1, 0xf7, 0x76, 0x8d, 0x7d, 0x0b, 0x8e, 0x86, 0x32, 0x87, 0x8e, 0x71, + 0xf8, 0xf1, 0x4f, 0x07, 0x39, 0x44, 0xc7, 0x88, 0x25, 0xdb, 0x72, 0x3d, 0x9f, 0x6c, 0xf2, 0xf0, + 0x64, 0x97, 0x5d, 0x6f, 0x90, 0xb3, 0x2f, 0x41, 0x2e, 0x60, 0x86, 0x8b, 0xea, 0x90, 0xf1, 0xf8, + 0xdf, 0x9c, 0xc1, 0xca, 0x70, 0x06, 0x0b, 0xb4, 0x88, 0xd5, 0x12, 0xe8, 0xca, 0x5f, 0x4a, 0x00, + 0xa1, 0x35, 0xf2, 0xd7, 0x53, 0xc6, 0x48, 0x78, 0xc6, 0x95, 0x73, 0xf2, 0x9e, 0xc3, 0x33, 0x46, + 0x20, 0xc4, 0xd4, 0xef, 0x4a, 0xc0, 0xf4, 0x96, 0x58, 0xbd, 0x7f, 0xfd, 0x79, 0xb0, 0x05, 0x93, + 0xd8, 0xf2, 0x1c, 0xd3, 0xbf, 0x31, 0xf0, 0xf8, 0xb0, 0x39, 0x8f, 0x19, 0x54, 0xcd, 0xf2, 0x9c, + 0xfd, 0xb0, 0x04, 0x08, 0x5a, 0x21, 0x7e, 0x7c, 0x34, 0x09, 0xb3, 0xc3, 0x50, 0xd1, 0x59, 0x28, + 0x19, 0x0e, 0xa6, 0x05, 0xd1, 0x77, 0x38, 0x8b, 0xa2, 0x98, 0x9b, 0x1d, 0x15, 0x88, 0x67, 0x49, + 0x84, 0x8b, 0x80, 0xde, 0x9b, 0x2b, 0x59, 0x0c, 0x28, 0x50, 0xc3, 0xd3, 0x84, 0x92, 0x78, 0x2a, + 0x67, 0x5b, 0x6f, 0xeb, 0x96, 0x21, 0x5c, 0xee, 0x43, 0xd9, 0x7c, 0xf1, 0xdc, 0x4e, 0x95, 0x91, + 0x40, 0x35, 0x98, 0x14, 0xd4, 0x52, 0x87, 0xa7, 0x26, 0x70, 0xd1, 0x69, 0xc8, 0x87, 0x0d, 0x03, + 0xf5, 0x46, 0x52, 0x6a, 0x2e, 0x64, 0x17, 0x46, 0x59, 0x9e, 0xf4, 0x81, 0x96, 0x87, 0x3b, 0x7c, + 0x3f, 0x94, 0x84, 0x29, 0x15, 0xb7, 0xfe, 0xe6, 0x4f, 0xcb, 0x26, 0x00, 0x5b, 0xaa, 0x44, 0x93, + 0xf2, 0x99, 0xb9, 0x87, 0xf5, 0x9e, 0x65, 0x44, 0x96, 0x5d, 0xef, 0x6b, 0x35, 0x43, 0xbf, 0x93, + 0x80, 0x7c, 0x78, 0x86, 0xfe, 0x56, 0x1a, 0x2d, 0xb4, 0x1e, 0xa8, 0x29, 0xb6, 0x51, 0xfe, 0xf0, + 0x30, 0x35, 0x35, 0x20, 0xcd, 0x23, 0xf4, 0xd3, 0x97, 0x92, 0x90, 0xe6, 0x97, 0x6e, 0x37, 0x06, + 0x7c, 0xdb, 0x91, 0x8f, 0x30, 0x17, 0xc4, 0x3b, 0xd6, 0xb1, 0xae, 0xed, 0x83, 0x50, 0x24, 0x41, + 0x7d, 0xe4, 0x26, 0xaf, 0x74, 0xae, 0x40, 0x63, 0xf3, 0xe0, 0x60, 0x13, 0x9a, 0x87, 0x1c, 0x01, + 0x0b, 0xf4, 0x30, 0x81, 0x81, 0x8e, 0x7e, 0xa7, 0xc6, 0x4a, 0xd0, 0x45, 0x40, 0x7b, 0x7e, 0xa6, + 0x45, 0x0b, 0x18, 0x21, 0x9d, 0x2b, 0xd0, 0x17, 0xc9, 0xa7, 0x82, 0x5a, 0x81, 0x72, 0x3f, 0x00, + 0xe9, 0x89, 0xc6, 0xb2, 0x92, 0xfc, 0x67, 0xb2, 0x49, 0xc9, 0x32, 0xcd, 0x4c, 0x7e, 0x9b, 0xc4, + 0xdc, 0xe4, 0xbe, 0xf0, 0x9f, 0x47, 0x29, 0xcd, 0x31, 0x16, 0xc6, 0x9f, 0xbd, 0x39, 0x3f, 0xb7, + 0xaf, 0x77, 0xda, 0x65, 0x25, 0x86, 0x8e, 0x12, 0x97, 0x91, 0x20, 0xce, 0x73, 0x34, 0x7d, 0x80, + 0xea, 0x20, 0xdf, 0xc4, 0xfb, 0x9a, 0xc3, 0x7f, 0x49, 0x5e, 0xdb, 0xc1, 0xe2, 0x2d, 0xf4, 0x13, + 0x8b, 0x31, 0x39, 0xe2, 0xc5, 0x25, 0xdb, 0xb4, 0xf8, 0x16, 0x66, 0xf1, 0x26, 0xde, 0x57, 0x39, + 0xde, 0x55, 0x8c, 0xcb, 0x0f, 0x90, 0xd5, 0xf2, 0xfa, 0x1f, 0xfc, 0xcc, 0xf9, 0x93, 0xa1, 0x7c, + 0xe7, 0x1d, 0x3f, 0xb1, 0xc7, 0xa6, 0x98, 0x38, 0xbe, 0x28, 0x30, 0x42, 0xa1, 0xdb, 0xdb, 0x10, + 0x8a, 0x15, 0xa4, 0x83, 0x63, 0x90, 0x00, 0x3f, 0x12, 0x83, 0x84, 0x96, 0xe8, 0xf3, 0x81, 0x0d, + 0x48, 0x8c, 0x1a, 0x4d, 0x58, 0x3a, 0x39, 0x12, 0x5d, 0xf9, 0x47, 0x94, 0xff, 0x24, 0xc1, 0x89, + 0x01, 0x69, 0xf6, 0xbb, 0x6c, 0x00, 0x72, 0x42, 0x95, 0x54, 0x2a, 0xc4, 0x05, 0x9e, 0x7b, 0x5b, + 0x1c, 0x53, 0xce, 0x80, 0x21, 0x78, 0x7b, 0x8c, 0x19, 0xd7, 0x64, 0xbf, 0x2a, 0xc1, 0x4c, 0xb8, + 0x03, 0xfe, 0x50, 0x1a, 0x90, 0x0f, 0x37, 0xcd, 0x07, 0xf1, 0xc0, 0x38, 0x83, 0x08, 0xf7, 0x3f, + 0x42, 0x04, 0xdd, 0x08, 0x34, 0x06, 0x4b, 0x27, 0x5e, 0x1c, 0x9b, 0x29, 0xa2, 0x63, 0xb1, 0x9a, + 0x83, 0xcd, 0xcd, 0x97, 0x24, 0x48, 0x6d, 0xda, 0x76, 0x1b, 0xbd, 0x17, 0xa6, 0x2c, 0xdb, 0xd3, + 0xc8, 0xca, 0xc2, 0x2d, 0x8d, 0xa7, 0x0e, 0x98, 0x36, 0xae, 0x1d, 0xc8, 0xab, 0x3f, 0x7c, 0x73, + 0x7e, 0x10, 0x33, 0x6e, 0xcf, 0xa1, 0x64, 0xd9, 0x5e, 0x95, 0x02, 0x35, 0x59, 0x76, 0x61, 0x07, + 0x0a, 0xd1, 0xe6, 0x98, 0xc6, 0xae, 0x8c, 0x6a, 0xae, 0x30, 0xb2, 0xa9, 0xfc, 0x76, 0xa8, 0x1d, + 0xf6, 0xb3, 0x43, 0x7f, 0x42, 0x66, 0xee, 0x9b, 0x40, 0xbe, 0xd1, 0x7f, 0x3d, 0xf4, 0x2a, 0x4c, + 0x8a, 0xeb, 0xa0, 0xd2, 0xb8, 0x57, 0x4d, 0xc3, 0xfc, 0xe4, 0xc8, 0x34, 0x5f, 0xfb, 0xb9, 0x04, + 0x9c, 0x58, 0xb2, 0x2d, 0x97, 0x27, 0x7a, 0xf8, 0xaa, 0x66, 0xc9, 0xe5, 0x7d, 0xf4, 0xf0, 0x90, + 0x34, 0x54, 0x7e, 0x30, 0xd9, 0x74, 0x03, 0x4a, 0xc4, 0xc4, 0x1a, 0xb6, 0xf5, 0x16, 0x73, 0x4d, + 0x05, 0xbb, 0xdd, 0xe2, 0x3d, 0xba, 0x89, 0xf7, 0x09, 0x5d, 0x0b, 0xdf, 0x8e, 0xd0, 0x4d, 0xde, + 0x1b, 0x5d, 0x0b, 0xdf, 0x0e, 0xd1, 0x0d, 0xce, 0x0c, 0xa5, 0x22, 0x37, 0x90, 0xae, 0x40, 0x92, + 0xa8, 0xc2, 0x89, 0x43, 0x28, 0x0f, 0x82, 0x10, 0x32, 0x6b, 0x0d, 0x38, 0xc1, 0x33, 0x05, 0xee, + 0xc6, 0x0e, 0xe5, 0x28, 0xa6, 0x03, 0x7a, 0x11, 0xef, 0xc7, 0xa4, 0x0d, 0xf2, 0x63, 0xa5, 0x0d, + 0xce, 0xff, 0xbc, 0x04, 0x10, 0xe4, 0xcc, 0xd0, 0xa3, 0x70, 0xbc, 0xba, 0xb1, 0xbe, 0x1c, 0x5c, + 0xc6, 0x08, 0x6d, 0xad, 0x8b, 0x53, 0x1a, 0x6e, 0x17, 0x1b, 0xe6, 0x8e, 0x89, 0x5b, 0xe8, 0x21, + 0x98, 0x89, 0x42, 0x93, 0xaf, 0xda, 0xb2, 0x2c, 0xcd, 0xe5, 0x5f, 0xbf, 0xbb, 0x90, 0x61, 0x31, + 0x02, 0x6e, 0xa1, 0x73, 0x70, 0x74, 0x10, 0xae, 0xbe, 0xbe, 0x22, 0x27, 0xe6, 0x0a, 0xaf, 0xdf, + 0x5d, 0xc8, 0xfa, 0xc1, 0x04, 0x52, 0x00, 0x85, 0x21, 0x39, 0xbd, 0xe4, 0x1c, 0xbc, 0x7e, 0x77, + 0x21, 0xcd, 0x96, 0x0c, 0xbf, 0xc5, 0xf1, 0x8d, 0x00, 0x75, 0x6b, 0xc7, 0xd1, 0x0d, 0xaa, 0x1a, + 0xe6, 0xe0, 0x58, 0x7d, 0xfd, 0xaa, 0x5a, 0x59, 0x6a, 0xd6, 0x37, 0xd6, 0xfb, 0x4e, 0x04, 0x44, + 0xeb, 0x96, 0x37, 0xb6, 0xaa, 0xab, 0x35, 0xad, 0x51, 0x5f, 0x59, 0x67, 0x57, 0xae, 0x22, 0x75, + 0xef, 0x59, 0x6f, 0xd6, 0xd7, 0x6a, 0x72, 0xa2, 0x7a, 0x65, 0xe8, 0x76, 0xdc, 0x7d, 0x91, 0xc5, + 0x18, 0x98, 0xa3, 0xc8, 0x46, 0xdc, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xbf, 0x2e, 0x6f, 0x47, + 0xe8, 0xa7, 0x00, 0x00, } r := bytes.NewReader(gzipped) gzipr, err := compress_gzip.NewReader(r) @@ -2366,6 +2443,41 @@ func (this *Description) Equal(that interface{}) bool { if this.Details != that1.Details { return false } + if !this.Metadata.Equal(&that1.Metadata) { + return false + } + return true +} +func (this *Metadata) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Metadata) + if !ok { + that2, ok := that.(Metadata) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.ProfilePicUri != that1.ProfilePicUri { + return false + } + if len(this.SocialHandleUris) != len(that1.SocialHandleUris) { + return false + } + for i := range this.SocialHandleUris { + if this.SocialHandleUris[i] != that1.SocialHandleUris[i] { + return false + } + } return true } func (this *UnbondingDelegationEntry) Equal(that interface{}) bool { @@ -2703,6 +2815,16 @@ func (m *Description) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintStaking(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 if len(m.Details) > 0 { i -= len(m.Details) copy(dAtA[i:], m.Details) @@ -2741,6 +2863,45 @@ func (m *Description) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Metadata) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Metadata) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Metadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SocialHandleUris) > 0 { + for iNdEx := len(m.SocialHandleUris) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SocialHandleUris[iNdEx]) + copy(dAtA[i:], m.SocialHandleUris[iNdEx]) + i = encodeVarintStaking(dAtA, i, uint64(len(m.SocialHandleUris[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.ProfilePicUri) > 0 { + i -= len(m.ProfilePicUri) + copy(dAtA[i:], m.ProfilePicUri) + i = encodeVarintStaking(dAtA, i, uint64(len(m.ProfilePicUri))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Validator) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2762,20 +2923,20 @@ func (m *Validator) MarshalToSizedBuffer(dAtA []byte) (int, error) { var l int _ = l if len(m.UnbondingIds) > 0 { - dAtA5 := make([]byte, len(m.UnbondingIds)*10) - var j4 int + dAtA6 := make([]byte, len(m.UnbondingIds)*10) + var j5 int for _, num := range m.UnbondingIds { for num >= 1<<7 { - dAtA5[j4] = uint8(uint64(num)&0x7f | 0x80) + dAtA6[j5] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j4++ + j5++ } - dAtA5[j4] = uint8(num) - j4++ + dAtA6[j5] = uint8(num) + j5++ } - i -= j4 - copy(dAtA[i:], dAtA5[:j4]) - i = encodeVarintStaking(dAtA, i, uint64(j4)) + i -= j5 + copy(dAtA[i:], dAtA6[:j5]) + i = encodeVarintStaking(dAtA, i, uint64(j5)) i-- dAtA[i] = 0x6a } @@ -2804,12 +2965,12 @@ func (m *Validator) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x52 - n7, err7 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.UnbondingTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.UnbondingTime):]) - if err7 != nil { - return 0, err7 + n8, err8 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.UnbondingTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.UnbondingTime):]) + if err8 != nil { + return 0, err8 } - i -= n7 - i = encodeVarintStaking(dAtA, i, uint64(n7)) + i -= n8 + i = encodeVarintStaking(dAtA, i, uint64(n8)) i-- dAtA[i] = 0x4a if m.UnbondingHeight != 0 { @@ -3219,12 +3380,12 @@ func (m *UnbondingDelegationEntry) MarshalToSizedBuffer(dAtA []byte) (int, error } i-- dAtA[i] = 0x1a - n10, err10 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) - if err10 != nil { - return 0, err10 + n11, err11 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) + if err11 != nil { + return 0, err11 } - i -= n10 - i = encodeVarintStaking(dAtA, i, uint64(n10)) + i -= n11 + i = encodeVarintStaking(dAtA, i, uint64(n11)) i-- dAtA[i] = 0x12 if m.CreationHeight != 0 { @@ -3285,12 +3446,12 @@ func (m *RedelegationEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x1a - n11, err11 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) - if err11 != nil { - return 0, err11 + n12, err12 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) + if err12 != nil { + return 0, err12 } - i -= n11 - i = encodeVarintStaking(dAtA, i, uint64(n11)) + i -= n12 + i = encodeVarintStaking(dAtA, i, uint64(n12)) i-- dAtA[i] = 0x12 if m.CreationHeight != 0 { @@ -3421,12 +3582,12 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x10 } - n13, err13 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingTime):]) - if err13 != nil { - return 0, err13 + n14, err14 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingTime):]) + if err14 != nil { + return 0, err14 } - i -= n13 - i = encodeVarintStaking(dAtA, i, uint64(n13)) + i -= n14 + i = encodeVarintStaking(dAtA, i, uint64(n14)) i-- dAtA[i] = 0xa return len(dAtA) - i, nil @@ -3828,6 +3989,27 @@ func (m *Description) Size() (n int) { if l > 0 { n += 1 + l + sovStaking(uint64(l)) } + l = m.Metadata.Size() + n += 1 + l + sovStaking(uint64(l)) + return n +} + +func (m *Metadata) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ProfilePicUri) + if l > 0 { + n += 1 + l + sovStaking(uint64(l)) + } + if len(m.SocialHandleUris) > 0 { + for _, s := range m.SocialHandleUris { + l = len(s) + n += 1 + l + sovStaking(uint64(l)) + } + } return n } @@ -4799,6 +4981,153 @@ func (m *Description) Unmarshal(dAtA []byte) error { } m.Details = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStaking + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthStaking + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipStaking(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthStaking + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Metadata) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Metadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProfilePicUri", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthStaking + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthStaking + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProfilePicUri = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SocialHandleUris", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthStaking + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthStaking + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SocialHandleUris = append(m.SocialHandleUris, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipStaking(dAtA[iNdEx:]) diff --git a/x/staking/types/validator.go b/x/staking/types/validator.go index c2e442d4c55a..6665c037b793 100644 --- a/x/staking/types/validator.go +++ b/x/staking/types/validator.go @@ -3,6 +3,7 @@ package types import ( "bytes" "fmt" + "net/url" "sort" "strings" "time" @@ -188,13 +189,14 @@ func (v Validator) IsUnbonding() bool { // constant used in flags to indicate that description field should not be updated const DoNotModifyDesc = "[do-not-modify]" -func NewDescription(moniker, identity, website, securityContact, details string) Description { +func NewDescription(moniker, identity, website, securityContact, details string, metadata Metadata) Description { return Description{ Moniker: moniker, Identity: identity, Website: website, SecurityContact: securityContact, Details: details, + Metadata: metadata, } } @@ -221,13 +223,18 @@ func (d Description) UpdateDescription(d2 Description) (Description, error) { d2.Details = d.Details } + if d2.Metadata.ProfilePicUri == DoNotModifyDesc { + d2.Metadata.ProfilePicUri = d.Metadata.ProfilePicUri + } + return NewDescription( d2.Moniker, d2.Identity, d2.Website, d2.SecurityContact, d2.Details, - ).EnsureLength() + d.Metadata, + ).Validate() } // EnsureLength ensures the length of a validator's description. @@ -255,6 +262,40 @@ func (d Description) EnsureLength() (Description, error) { return d, nil } +func (d Description) IsEmpty() bool { + return d.Moniker == "" && d.Details == "" && d.Identity == "" && d.Website == "" && d.SecurityContact == "" && + d.Metadata.ProfilePicUri == "" && len(d.Metadata.SocialHandleUris) == 0 +} + +// Validate calls metadata.Validate() description.EnsureLength() +func (d Description) Validate() (Description, error) { + if err := d.Metadata.Validate(); err != nil { + return d, err + } + + return d.EnsureLength() +} + +// Validate checks that the metadata fields are valid. For the ProfilePicUri, checks if a valid URI. +func (m Metadata) Validate() error { + if m.ProfilePicUri != "" { + _, err := url.ParseRequestURI(m.ProfilePicUri) + if err != nil { + return errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid profile_pic_uri format: %s, err: %s", m.ProfilePicUri, err) + } + } + + if m.SocialHandleUris != nil { + for _, socialHandleUri := range m.SocialHandleUris { + _, err := url.ParseRequestURI(socialHandleUri) + if err != nil { + return errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid social_handle_uri: %s, err: %s", socialHandleUri, err) + } + } + } + return nil +} + // ModuleValidatorUpdate returns a appmodule.ValidatorUpdate from a staking validator type // with the full validator power. // It replaces the previous ABCIValidatorUpdate function. From 617d54761f00b3d27a239337736ef44fd43af39d Mon Sep 17 00:00:00 2001 From: Eric Mokaya <4112301+ziscky@users.noreply.github.com> Date: Tue, 1 Oct 2024 10:37:25 +0300 Subject: [PATCH 06/10] docs: add instructions to change DefaultGenesis (#21680) --- docs/build/building-apps/06-app-go-genesis.md | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 docs/build/building-apps/06-app-go-genesis.md diff --git a/docs/build/building-apps/06-app-go-genesis.md b/docs/build/building-apps/06-app-go-genesis.md new file mode 100644 index 000000000000..b9902858d7fe --- /dev/null +++ b/docs/build/building-apps/06-app-go-genesis.md @@ -0,0 +1,47 @@ +--- +sidebar_position: 1 +--- + +### Modifying the `DefaultGenesis` + +It is possible to modify the DefaultGenesis parameters for modules by wrapping the module, providing it to the `*module.Manager` and injecting it with `depinject`. + +Example ( staking ) : + +```go +type CustomStakingModule struct { + staking.AppModule + cdc codec.Codec +} + +// DefaultGenesis will override the Staking module DefaultGenesis AppModuleBasic method. +func (cm CustomStakingModule) DefaultGenesis() json.RawMessage { + params := stakingtypes.DefaultParams() + params.BondDenom = "mydenom" + + return cm.cdc.MustMarshalJSON(&stakingtypes.GenesisState{ + Params: params, + }) +} + +// option 1 ( for depinject users ): override previous module manager +depinject.Inject( +// ... provider/invoker/supplier +&moduleManager, +) + +oldStakingModule,_ := moduleManager.Modules()[stakingtypes.ModuleName].(staking.AppModule) +moduleManager.Modules()[stakingtypes.ModuleName] = CustomStakingModule{ + AppModule: oldStakingModule, + cdc: appCodec, +} + +// option 2 ( for non depinject users ): use new module manager +moduleManager := module.NewManagerFromMap(map[string]appmodule.AppModule{ +stakingtypes.ModuleName: CustomStakingModule{cdc: appCodec, AppModule: staking.NewAppModule(...)}, +// other modules ... +}) + +// set the module manager +app.ModuleManager = moduleManager +``` From 73ee336359285d88e786919ab693c016e7cc2935 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Tue, 1 Oct 2024 03:40:42 -0400 Subject: [PATCH 07/10] feat(schema): add API descriptors, struct, oneof & list types, and wire encoding spec (#21482) Co-authored-by: marbar3778 Co-authored-by: Marko --- schema/api.go | 98 +++++++++++++++++++++++++++++++++ schema/field.go | 15 +++++- schema/kind.go | 120 +++++++++++++++++++++++++++++++++++++++-- schema/oneof.go | 43 +++++++++++++++ schema/state_object.go | 13 +++-- schema/struct.go | 21 ++++++++ 6 files changed, 302 insertions(+), 8 deletions(-) create mode 100644 schema/api.go create mode 100644 schema/oneof.go create mode 100644 schema/struct.go diff --git a/schema/api.go b/schema/api.go new file mode 100644 index 000000000000..3d8224a9a6d9 --- /dev/null +++ b/schema/api.go @@ -0,0 +1,98 @@ +package schema + +// APIDescriptor is a public versioned descriptor of an API. +// +// An APIDescriptor can be used as a native descriptor of an API's encoding. +// The native binary encoding of API requests and responses is to encode the input and output +// fields using value binary encoding. +// The native JSON encoding would be to encode the fields as a JSON object, canonically +// sorted by field name with no extra whitespace. +// Thus, APIDefinitions have deterministic binary and JSON encodings. +// +// APIDefinitions have a strong definition of compatibility between different versions +// of the same API. +// It is an INCOMPATIBLE change to add new input fields to existing methods or to remove or modify +// existing input or output fields. +// Input fields also cannot reference any unsealed structs, directly or transitively, +// because these types allow adding new fields. +// Adding new input fields to a method introduces the possibility that a newer client +// will send an incomprehensible message to an older server. +// The only safe ways that input field schemas can be extended are by adding +// new values to EnumType's and new cases to OneOfType's. +// It is a COMPATIBLE change to add new methods to an API and to add new output fields +// to existing methods. +// Output fields can reference any sealed or unsealed StructType, directly or transitively. +// +// Existing protobuf APIs could also be mapped into APIDefinitions, and used in the following ways: +// - to produce, user-friendly deterministic JSON +// - to produce a deterministic binary encoding +// - to check for compatibility in a way that is more appropriate to blockchain applications +// - to use any code generators designed to support this spec as an alternative to protobuf +// Also, a standardized way of serializing schema types as protobuf could be defined which +// maps to the original protobuf encoding, so that schemas can be used as an interop +// layer between different less expressive encoding systems. +// +// Existing EVM contract APIs expressed in Solidity could be mapped into APIDefinitions, and +// a mapping of all schema values to ABI encoding could be defined which preserves the +// original ABI encoding. +// +// In this way, we can define an interop layer between contracts in the EVM world, +// SDK modules accepting protobuf types, and any API using this schema system natively. +type APIDescriptor struct { + // Name is the versioned name of the API. + Name string + + // Methods is the list of methods in the API. + // It is a COMPATIBLE change to add new methods to an API. + // If a newer client tries to call a method that an older server does not recognize it, + // an error will simply be returned. + Methods []MethodDescriptor +} + +// MethodDescriptor describes a method in the API. +type MethodDescriptor struct { + // Name is the name of the method. + Name string + + // InputFields is the list of input fields for the method. + // + // It is an INCOMPATIBLE change to add, remove or update input fields to a method. + // The addition of new fields introduces the possibility that a newer client + // will send an incomprehensible message to an older server. + // InputFields can only reference sealed StructTypes, either directly and transitively. + // + // As a special case to represent protobuf service definitions, there can be a single + // unnamed struct input field that code generators can choose to either reference + // as a named struct or to expand inline as function arguments. + InputFields []Field + + // OutputFields is the list of output fields for the method. + // + // It is a COMPATIBLE change to add new output fields to a method, + // but existing output fields should not be removed or modified. + // OutputFields can reference any sealed or unsealed StructType, directly or transitively. + // If a newer client tries to call a method on an older server, the newer expected result output + // fields will simply be populated with the default values for that field kind. + // + // As a special case to represent protobuf service definitions, there can be a single + // unnamed struct output field. + // In this case, adding new output fields is an INCOMPATIBLE change (because protobuf service definitions + // don't allow this), but new fields can be added to the referenced struct if it is unsealed. + OutputFields []Field + + // Volatility is the volatility of the method. + Volatility Volatility +} + +// Volatility is the volatility of a method. +type Volatility int + +const ( + // PureVolatility indicates that the method can neither read nor write state. + PureVolatility Volatility = iota + // ReadonlyVolatility indicates that the method can read state but not write state. + ReadonlyVolatility + + // VolatileVolatility indicates that the method can read and write state. + VolatileVolatility +) diff --git a/schema/field.go b/schema/field.go index dfbae6ed1b97..b2bc76a2e3b6 100644 --- a/schema/field.go +++ b/schema/field.go @@ -15,8 +15,21 @@ type Field struct { // Nullable indicates whether null values are accepted for the field. Key fields CANNOT be nullable. Nullable bool `json:"nullable,omitempty"` - // ReferencedType is the referenced type name when Kind is EnumKind. + // ReferencedType is the referenced type name when Kind is EnumKind, StructKind or OneOfKind. ReferencedType string `json:"referenced_type,omitempty"` + + // ElementKind is the element type when Kind is ListKind. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + ElementKind Kind `json:"element_kind,omitempty"` + + // Size specifies the size or max-size of a field. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // Its specific meaning may vary depending on the field kind. + // For IntNKind and UintNKind fields, it specifies the bit width of the field. + // For StringKind, BytesKind, AddressKind, and JSONKind, fields it specifies the maximum length rather than a fixed length. + // If it is 0, such fields have no maximum length. + // It is invalid to have a non-zero Size for other kinds. + Size uint32 `json:"size,omitempty"` } // Validate validates the field. diff --git a/schema/kind.go b/schema/kind.go index 5eedee68c244..0992b297baa7 100644 --- a/schema/kind.go +++ b/schema/kind.go @@ -10,12 +10,25 @@ import ( // Kind represents the basic type of a field in an object. // Each kind defines the following encodings: -// Go Encoding: the golang type which should be accepted by listeners and +// +// - Go Encoding: the golang type which should be accepted by listeners and // generated by decoders when providing entity updates. -// JSON Encoding: the JSON encoding which should be used when encoding the field to JSON. +// - JSON Encoding: the JSON encoding which should be used when encoding the field to JSON. +// - Key Binary Encoding: the encoding which should be used when encoding the field +// as a key in binary messages. Some encodings specify a terminal and non-terminal form +// depending on whether or not the field is the last field in the key. +// - Value Binary Encoding: the encoding which should be used when encoding the field +// as a value in binary messages. +// // When there is some non-determinism in an encoding, kinds should specify what // values they accept and also what is the canonical, deterministic encoding which // should be preferably emitted by serializers. +// +// Binary encodings were chosen based on what is likely to be the most convenient default binary encoding +// for state management implementations. This encoding allows for sorted keys whenever it is possible for a kind +// and is deterministic. +// Modules that use the specified encoding natively will have a trivial decoder implementation because the +// encoding is already in the correct format after any initial prefix bytes are stripped. type Kind int const ( @@ -25,54 +38,82 @@ const ( // StringKind is a string type. // Go Encoding: UTF-8 string with no null characters. // JSON Encoding: string + // Key Binary Encoding: + // non-terminal: UTF-8 string with no null characters suffixed with a null character + // terminal: UTF-8 string with no null characters + // Value Binary Encoding: the same value binary encoding as BytesKind. StringKind - // BytesKind is a bytes type. + // BytesKind represents a byte array. // Go Encoding: []byte // JSON Encoding: base64 encoded string, canonical values should be encoded with standard encoding and padding. // Either standard or URL encoding with or without padding should be accepted. + // Key Binary Encoding: + // non-terminal: length prefixed bytes where the width of the length prefix is 1, 2, 3 or 4 bytes depending on + // the field's MaxLength (defaulting to 4 bytes). + // Length prefixes should be big-endian encoded. + // Values larger than 2^32 bytes are not supported (likely key-value stores impose a lower limit). + // terminal: raw bytes with no length prefix + // Value Binary Encoding: two 32-bit unsigned little-endian integers, the first one representing the offset of the + // value in the buffer and the second one representing the length of the value. BytesKind // Int8Kind represents an 8-bit signed integer. // Go Encoding: int8 // JSON Encoding: number + // Key Binary Encoding: 1-byte two's complement encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 1-byte two's complement encoding. Int8Kind // Uint8Kind represents an 8-bit unsigned integer. // Go Encoding: uint8 // JSON Encoding: number + // Key Binary Encoding: 1-byte unsigned encoding. + // Value Binary Encoding: 1-byte unsigned encoding. Uint8Kind // Int16Kind represents a 16-bit signed integer. // Go Encoding: int16 // JSON Encoding: number + // Key Binary Encoding: 2-byte two's complement big-endian encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 2 byte two's complement little-endian encoding. Int16Kind // Uint16Kind represents a 16-bit unsigned integer. // Go Encoding: uint16 // JSON Encoding: number + // Key Binary Encoding: 2-byte unsigned big-endian encoding. + // Value Binary Encoding: 2-byte unsigned little-endian encoding. Uint16Kind // Int32Kind represents a 32-bit signed integer. // Go Encoding: int32 // JSON Encoding: number + // Key Binary Encoding: 4-byte two's complement big-endian encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 4-byte two's complement little-endian encoding. Int32Kind // Uint32Kind represents a 32-bit unsigned integer. // Go Encoding: uint32 // JSON Encoding: number + // Key Binary Encoding: 4-byte unsigned big-endian encoding. + // Value Binary Encoding: 4-byte unsigned little-endian encoding. Uint32Kind // Int64Kind represents a 64-bit signed integer. // Go Encoding: int64 // JSON Encoding: base10 integer string which matches the IntegerFormat regex // The canonical encoding should include no leading zeros. + // Key Binary Encoding: 8-byte two's complement big-endian encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 8-byte two's complement little-endian encoding. Int64Kind // Uint64Kind represents a 64-bit unsigned integer. // Go Encoding: uint64 // JSON Encoding: base10 integer string which matches the IntegerFormat regex // Canonically encoded values should include no leading zeros. + // Key Binary Encoding: 8-byte unsigned big-endian encoding. + // Value Binary Encoding: 8-byte unsigned little-endian encoding. Uint64Kind // IntegerKind represents an arbitrary precision integer number. @@ -98,6 +139,8 @@ const ( // BoolKind represents a boolean true or false value. // Go Encoding: bool // JSON Encoding: boolean + // Key Binary Encoding: 1-byte encoding where 0 is false and 1 is true. + // Value Binary Encoding: 1-byte encoding where 0 is false and 1 is true. BoolKind // TimeKind represents a nanosecond precision UNIX time value (with zero representing January 1, 1970 UTC). @@ -107,6 +150,8 @@ const ( // Canonical values should be encoded with UTC time zone Z, nanoseconds should // be encoded with no trailing zeros, and T time values should always be present // even at 00:00:00. + // Key Binary Encoding: 8-byte two's complement big-endian encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 8-byte two's complement little-endian encoding. TimeKind // DurationKind represents the elapsed time between two nanosecond precision time values. @@ -114,24 +159,35 @@ const ( // Go Encoding: time.Duration // JSON Encoding: the number of seconds as a decimal string with no trailing zeros followed by // a lowercase 's' character to represent seconds. + // Key Binary Encoding: 8-byte two's complement big-endian encoding, with the first bit inverted for sorting. + // Value Binary Encoding: 8-byte two's complement little-endian encoding. DurationKind // Float32Kind represents an IEEE-754 32-bit floating point number. // Go Encoding: float32 // JSON Encoding: number + // Key Binary Encoding: 4-byte IEEE-754 encoding. + // Value Binary Encoding: 4-byte IEEE-754 encoding. Float32Kind // Float64Kind represents an IEEE-754 64-bit floating point number. // Go Encoding: float64 // JSON Encoding: number + // Key Binary Encoding: 8-byte IEEE-754 encoding. + // Value Binary Encoding: 8-byte IEEE-754 encoding. Float64Kind // AddressKind represents an account address which is represented by a variable length array of bytes. // Addresses usually have a human-readable rendering, such as bech32, and tooling should provide - // a way for apps to define a string encoder for friendly user-facing display. + // a way for apps to define a string encoder for friendly user-facing display. Addresses have a maximum + // supported length of 63 bytes. // Go Encoding: []byte // JSON Encoding: addresses should be encoded as strings using the human-readable address renderer // provided to the JSON encoder. + // Key Binary Encoding: + // non-terminal: bytes prefixed with 1-byte length prefix + // terminal: raw bytes with no length prefix + // Value Binary Encoding: bytes prefixed with 1-byte length prefix. AddressKind // EnumKind represents a value of an enum type. @@ -139,12 +195,68 @@ const ( // definition. // Go Encoding: string // JSON Encoding: string + // Key Binary Encoding: the same binary encoding as the EnumType's numeric kind. + // Value Binary Encoding: the same binary encoding as the EnumType's numeric kind. EnumKind // JSONKind represents arbitrary JSON data. // Go Encoding: json.RawMessage // JSON Encoding: any valid JSON value + // Key Binary Encoding: string encoding + // Value Binary Encoding: string encoding JSONKind + + // UIntNKind represents a signed integer type with a width in bits specified by the Size field in the + // field definition. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // N must be a multiple of 8, and it is invalid for N to equal 8, 16, 32, 64 as there are more specific + // types for these widths. + // Go Encoding: []byte where len([]byte) == Size / 8, little-endian encoded. + // JSON Encoding: base10 integer string matching the IntegerFormat regex, canonically with no leading zeros. + // Key Binary Encoding: N / 8 bytes big-endian encoded + // Value Binary Encoding: N / 8 bytes little-endian encoded + UIntNKind + + // IntNKind represents an unsigned integer type with a width in bits specified by the Size field in the + // field definition. N must be a multiple of 8. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // N must be a multiple of 8, and it is invalid for N to equal 8, 16, 32, 64 as there are more specific + // types for these widths. + // Go Encoding: []byte where len([]byte) == Size / 8, two's complement little-endian encoded. + // JSON Encoding: base10 integer string matching the IntegerFormat regex, canonically with no leading zeros. + // Key Binary Encoding: N / 8 bytes big-endian two's complement encoded with the first bit inverted for sorting. + // Value Binary Encoding: N / 8 bytes little-endian two's complement encoded. + IntNKind + + // StructKind represents a struct object. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // Go Encoding: an array of type []interface{} where each element is of the respective field's kind type. + // JSON Encoding: an object where each key is the field name and the value is the field value. + // Canonically, keys are in alphabetical order with no extra whitespace. + // Key Binary Encoding: not valid as a key field. + // Value Binary Encoding: 32-bit unsigned little-endian length prefix, + // followed by the value binary encoding of each field in order. + StructKind + + // OneOfKind represents a field that can be one of a set of types. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // Go Encoding: the anonymous struct { Case string; Value interface{} }, aliased as OneOfValue. + // JSON Encoding: same as the case's struct encoding with "@type" set to the case name. + // Key Binary Encoding: not valid as a key field. + // Value Binary Encoding: the oneof's discriminant numeric value encoded as its discriminant kind + // followed by the encoded value. + OneOfKind + + // ListKind represents a list of elements. + // Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. + // Go Encoding: an array of type []interface{} where each element is of the respective field's kind type. + // JSON Encoding: an array of values where each element is the field value. + // Canonically, there is no extra whitespace. + // Key Binary Encoding: not valid as a key field. + // Value Binary Encoding: 32-bit unsigned little-endian size prefix indicating the size of the encoded data in bytes, + // followed by a 32-bit unsigned little-endian count of the number of elements in the list, + // followed by each element encoded with value binary encoding. + ListKind ) // MAX_VALID_KIND is the maximum valid kind value. diff --git a/schema/oneof.go b/schema/oneof.go new file mode 100644 index 000000000000..ec0cd6d649ae --- /dev/null +++ b/schema/oneof.go @@ -0,0 +1,43 @@ +package schema + +// OneOfType represents a oneof type. +// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. +type OneOfType struct { + // Name is the name of the oneof type. It must conform to the NameFormat regular expression. + Name string + + // Cases is a list of cases in the oneof type. + // It is a COMPATIBLE change to add new cases to a oneof type. + // If a newer client tries to send a message with a case that an older server does not recognize, + // the older server will simply reject it in a switch statement. + // It is INCOMPATIBLE to remove existing cases from a oneof type. + Cases []OneOfCase + + // DiscriminantKind is the kind of the discriminant field. + // It must be Uint8Kind, Int8Kind, Uint16Kind, Int16Kind, or Int32Kind. + DiscriminantKind Kind +} + +// OneOfCase represents a case in a oneof type. It is represented by a struct type internally with a discriminant value. +type OneOfCase struct { + // Name is the name of the case. It must conform to the NameFormat regular expression. + Name string + + // Discriminant is the discriminant value for the case. + Discriminant int32 + + // Kind is the kind of the case. ListKind is not allowed. + Kind Kind + + // Reference is the referenced type if Kind is EnumKind, StructKind, or OneOfKind. + ReferencedType string +} + +// OneOfValue is the golang runtime representation of a oneof value. +type OneOfValue = struct { + // Case is the name of the case. + Case string + + // Value is the value of the case. + Value interface{} +} diff --git a/schema/state_object.go b/schema/state_object.go index a4825726f685..eff8d1f98459 100644 --- a/schema/state_object.go +++ b/schema/state_object.go @@ -9,16 +9,23 @@ type StateObjectType struct { Name string `json:"name"` // KeyFields is a list of fields that make up the primary key of the object. - // It can be empty in which case indexers should assume that this object is + // It can be empty, in which case, indexers should assume that this object is // a singleton and only has one value. Field names must be unique within the // object between both key and value fields. - // Key fields CANNOT be nullable and Float32Kind, Float64Kind, and JSONKind types - // are not allowed. + // Key fields CANNOT be nullable and Float32Kind, Float64Kind, JSONKind, StructKind, + // OneOfKind, RepeatedKind, ListKind or ObjectKind + // are NOT ALLOWED. + // It is an INCOMPATIBLE change to add, remove or change fields in the key as this + // changes the underlying primary key of the object. KeyFields []Field `json:"key_fields,omitempty"` // ValueFields is a list of fields that are not part of the primary key of the object. // It can be empty in the case where all fields are part of the primary key. // Field names must be unique within the object between both key and value fields. + // ObjectKind fields are not allowed. + // It is a COMPATIBLE change to add new value fields to an object type because + // this does not affect the primary key of the object. + // Existing value fields should not be removed or modified. ValueFields []Field `json:"value_fields,omitempty"` // RetainDeletions is a flag that indicates whether the indexer should retain diff --git a/schema/struct.go b/schema/struct.go new file mode 100644 index 000000000000..20676a743ade --- /dev/null +++ b/schema/struct.go @@ -0,0 +1,21 @@ +package schema + +// StructType represents a struct type. +// Support for this is currently UNIMPLEMENTED, this notice will be removed when it is added. +type StructType struct { + // Name is the name of the struct type. + Name string + + // Fields is the list of fields in the struct. + // It is a COMPATIBLE change to add new fields to an unsealed struct, + // but it is an INCOMPATIBLE change to add new fields to a sealed struct. + // + // A sealed struct cannot reference any unsealed structs directly or + // transitively because these types allow adding new fields. + Fields []Field + + // Sealed is true if it is an INCOMPATIBLE change to add new fields to the struct. + // It is a COMPATIBLE change to change an unsealed struct to sealed, but it is + // an INCOMPATIBLE change to change a sealed struct to unsealed. + Sealed bool +} From 3a20261c78d7594e478ec7601eca67b4dc80fd6c Mon Sep 17 00:00:00 2001 From: Matt Kocubinski Date: Tue, 1 Oct 2024 03:01:06 -0500 Subject: [PATCH 08/10] refactor(runtime/v2): use StoreBuilder (#21989) --- runtime/v2/builder.go | 49 ++++--------------------------------- runtime/v2/module.go | 39 +++++++++++++++++++++++------ runtime/v2/store.go | 57 +++++++++++++++++++++++++++++++++++++++++++ runtime/v2/types.go | 2 +- simapp/v2/app_di.go | 30 +++++++++++++---------- 5 files changed, 112 insertions(+), 65 deletions(-) diff --git a/runtime/v2/builder.go b/runtime/v2/builder.go index c6fad39f41aa..b28ddbc741b4 100644 --- a/runtime/v2/builder.go +++ b/runtime/v2/builder.go @@ -6,28 +6,22 @@ import ( "errors" "fmt" "io" - "path/filepath" "cosmossdk.io/core/appmodule" appmodulev2 "cosmossdk.io/core/appmodule/v2" - "cosmossdk.io/core/server" "cosmossdk.io/core/store" "cosmossdk.io/core/transaction" "cosmossdk.io/runtime/v2/services" "cosmossdk.io/server/v2/appmanager" "cosmossdk.io/server/v2/stf" "cosmossdk.io/server/v2/stf/branch" - "cosmossdk.io/store/v2/db" - rootstore "cosmossdk.io/store/v2/root" ) // AppBuilder is a type that is injected into a container by the runtime/v2 module // (as *AppBuilder) which can be used to create an app which is compatible with // the existing app.go initialization conventions. type AppBuilder[T transaction.Tx] struct { - app *App[T] - config server.DynamicConfig - storeOptions *rootstore.Options + app *App[T] // the following fields are used to overwrite the default branch func(state store.ReaderMap) store.WriterMap @@ -99,6 +93,10 @@ func (a *AppBuilder[T]) Build(opts ...AppBuilderOption[T]) (*App[T], error) { } } + if a.app.db == nil { + return nil, fmt.Errorf("app.db is not set, it is required to build the app") + } + if err := a.app.moduleManager.RegisterServices(a.app); err != nil { return nil, err } @@ -122,37 +120,6 @@ func (a *AppBuilder[T]) Build(opts ...AppBuilderOption[T]) (*App[T], error) { } a.app.stf = stf - home := a.config.GetString(FlagHome) - scRawDb, err := db.NewDB( - db.DBType(a.config.GetString("store.app-db-backend")), - "application", - filepath.Join(home, "data"), - nil, - ) - if err != nil { - panic(err) - } - - var storeOptions rootstore.Options - if a.storeOptions != nil { - storeOptions = *a.storeOptions - } else { - storeOptions = rootstore.DefaultStoreOptions() - } - factoryOptions := &rootstore.FactoryOptions{ - Logger: a.app.logger, - RootDir: home, - Options: storeOptions, - StoreKeys: append(a.app.storeKeys, "stf"), - SCRawDB: scRawDb, - } - - rs, err := rootstore.CreateRootStore(factoryOptions) - if err != nil { - return nil, fmt.Errorf("failed to create root store: %w", err) - } - a.app.db = rs - appManagerBuilder := appmanager.Builder[T]{ STF: a.app.stf, DB: a.app.db, @@ -251,9 +218,3 @@ func AppBuilderWithPostTxExec[T transaction.Tx](postTxExec func(ctx context.Cont a.postTxExec = postTxExec } } - -func AppBuilderWithStoreOptions[T transaction.Tx](opts *rootstore.Options) AppBuilderOption[T] { - return func(a *AppBuilder[T]) { - a.storeOptions = opts - } -} diff --git a/runtime/v2/module.go b/runtime/v2/module.go index d4a9b4b534d9..8e8b7e0ce832 100644 --- a/runtime/v2/module.go +++ b/runtime/v2/module.go @@ -16,6 +16,7 @@ import ( reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" appmodulev2 "cosmossdk.io/core/appmodule/v2" "cosmossdk.io/core/comet" + "cosmossdk.io/core/event" "cosmossdk.io/core/header" "cosmossdk.io/core/registry" "cosmossdk.io/core/server" @@ -26,6 +27,7 @@ import ( "cosmossdk.io/log" "cosmossdk.io/runtime/v2/services" "cosmossdk.io/server/v2/stf" + rootstore "cosmossdk.io/store/v2/root" ) var ( @@ -40,19 +42,19 @@ type appModule[T transaction.Tx] struct { func (m appModule[T]) IsOnePerModuleType() {} func (m appModule[T]) IsAppModule() {} -func (m appModule[T]) RegisterServices(registar grpc.ServiceRegistrar) error { +func (m appModule[T]) RegisterServices(registrar grpc.ServiceRegistrar) error { autoCliQueryService, err := services.NewAutoCLIQueryService(m.app.moduleManager.modules) if err != nil { return err } - autocliv1.RegisterQueryServer(registar, autoCliQueryService) + autocliv1.RegisterQueryServer(registrar, autoCliQueryService) reflectionSvc, err := services.NewReflectionService() if err != nil { return err } - reflectionv1.RegisterReflectionServiceServer(registar, reflectionSvc) + reflectionv1.RegisterReflectionServiceServer(registrar, reflectionSvc) return nil } @@ -97,6 +99,7 @@ func init() { ProvideAppBuilder[transaction.Tx], ProvideEnvironment[transaction.Tx], ProvideModuleManager[transaction.Tx], + ProvideStoreBuilder, ), appconfig.Invoke(SetupAppBuilder), ) @@ -146,7 +149,12 @@ type AppInputs struct { InterfaceRegistrar registry.InterfaceRegistrar LegacyAmino registry.AminoRegistrar Logger log.Logger - DynamicConfig server.DynamicConfig `optional:"true"` // can be nil in client wiring + // StoreBuilder is a builder for a store/v2 RootStore satisfying the Store interface + StoreBuilder *StoreBuilder + // StoreOptions are required as input for the StoreBuilder. If not provided, the default options are used. + StoreOptions *rootstore.Options `optional:"true"` + // DynamicConfig can be nil in client wiring, but is required in server wiring. + DynamicConfig server.DynamicConfig `optional:"true"` } func SetupAppBuilder(inputs AppInputs) { @@ -157,8 +165,22 @@ func SetupAppBuilder(inputs AppInputs) { app.moduleManager.RegisterInterfaces(inputs.InterfaceRegistrar) app.moduleManager.RegisterLegacyAminoCodec(inputs.LegacyAmino) - if inputs.DynamicConfig != nil { - inputs.AppBuilder.config = inputs.DynamicConfig + if inputs.DynamicConfig == nil { + return + } + storeOptions := rootstore.DefaultStoreOptions() + if inputs.StoreOptions != nil { + storeOptions = *inputs.StoreOptions + } + var err error + app.db, err = inputs.StoreBuilder.Build( + inputs.Logger, + app.storeKeys, + inputs.DynamicConfig, + storeOptions, + ) + if err != nil { + panic(err) } } @@ -178,6 +200,7 @@ func ProvideEnvironment[T transaction.Tx]( appBuilder *AppBuilder[T], kvFactory store.KVStoreServiceFactory, headerService header.Service, + eventService event.Service, ) ( appmodulev2.Environment, store.KVStoreService, @@ -209,7 +232,7 @@ func ProvideEnvironment[T transaction.Tx]( env := appmodulev2.Environment{ Logger: logger, BranchService: stf.BranchService{}, - EventService: stf.NewEventService(), + EventService: eventService, GasService: stf.NewGasMeterService(), HeaderService: headerService, QueryRouterService: stf.NewQueryRouterService(), @@ -254,10 +277,12 @@ func DefaultServiceBindings() depinject.Config { } headerService header.Service = services.NewGenesisHeaderService(stf.HeaderService{}) cometService comet.Service = &services.ContextAwareCometInfoService{} + eventService = stf.NewEventService() ) return depinject.Supply( kvServiceFactory, headerService, cometService, + eventService, ) } diff --git a/runtime/v2/store.go b/runtime/v2/store.go index 40912ea41f48..6c45dd5e72db 100644 --- a/runtime/v2/store.go +++ b/runtime/v2/store.go @@ -3,11 +3,16 @@ package runtime import ( "errors" "fmt" + "path/filepath" + "cosmossdk.io/core/server" "cosmossdk.io/core/store" + "cosmossdk.io/log" "cosmossdk.io/server/v2/stf" storev2 "cosmossdk.io/store/v2" + "cosmossdk.io/store/v2/db" "cosmossdk.io/store/v2/proof" + "cosmossdk.io/store/v2/root" ) // NewKVStoreService creates a new KVStoreService. @@ -59,6 +64,58 @@ type Store interface { LastCommitID() (proof.CommitID, error) } +// StoreBuilder is a builder for a store/v2 RootStore satisfying the Store interface. +type StoreBuilder struct { + store Store +} + +// Build creates a new store/v2 RootStore. +func (sb *StoreBuilder) Build( + logger log.Logger, + storeKeys []string, + config server.DynamicConfig, + options root.Options, +) (Store, error) { + if sb.store != nil { + return sb.store, nil + } + home := config.GetString(flagHome) + scRawDb, err := db.NewDB( + db.DBType(config.GetString("store.app-db-backend")), + "application", + filepath.Join(home, "data"), + nil, + ) + if err != nil { + return nil, fmt.Errorf("failed to create SCRawDB: %w", err) + } + + factoryOptions := &root.FactoryOptions{ + Logger: logger, + RootDir: home, + Options: options, + // STF needs to store a bit of state + StoreKeys: append(storeKeys, "stf"), + SCRawDB: scRawDb, + } + + rs, err := root.CreateRootStore(factoryOptions) + if err != nil { + return nil, fmt.Errorf("failed to create root store: %w", err) + } + sb.store = rs + return sb.store, nil +} + +// Get returns the Store. Build must be called before calling Get or the result will be nil. +func (sb *StoreBuilder) Get() Store { + return sb.store +} + +func ProvideStoreBuilder() *StoreBuilder { + return &StoreBuilder{} +} + // StoreLoader allows for custom loading of the store, this is useful when upgrading the store from a previous version type StoreLoader func(store Store) error diff --git a/runtime/v2/types.go b/runtime/v2/types.go index baa20182b512..9018af921b1c 100644 --- a/runtime/v2/types.go +++ b/runtime/v2/types.go @@ -14,7 +14,7 @@ import ( const ( ModuleName = "runtime" - FlagHome = "home" + flagHome = "home" ) // validateProtoAnnotations validates that the proto annotations are correct. diff --git a/simapp/v2/app_di.go b/simapp/v2/app_di.go index a2fbb958dc0d..43ca45f99aed 100644 --- a/simapp/v2/app_di.go +++ b/simapp/v2/app_di.go @@ -64,10 +64,9 @@ func NewSimApp[T transaction.Tx]( viper *viper.Viper, ) *SimApp[T] { var ( - app = &SimApp[T]{} - appBuilder *runtime.AppBuilder[T] - err error - storeOptions = &root.Options{} + app = &SimApp[T]{} + appBuilder *runtime.AppBuilder[T] + err error // merge the AppConfig and other configuration in one config appConfig = depinject.Configs( @@ -149,6 +148,19 @@ func NewSimApp[T transaction.Tx]( ) ) + // the subsection of config that contains the store options (in app.toml [store.options] header) + // is unmarshaled into a store.Options struct and passed to the store builder. + // future work may move this specification and retrieval into store/v2. + // If these options are not specified then default values will be used. + if sub := viper.Sub("store.options"); sub != nil { + storeOptions := &root.Options{} + err := sub.Unmarshal(storeOptions) + if err != nil { + panic(err) + } + appConfig = depinject.Configs(appConfig, depinject.Supply(storeOptions)) + } + if err := depinject.Inject(appConfig, &appBuilder, &app.appCodec, @@ -160,15 +172,7 @@ func NewSimApp[T transaction.Tx]( panic(err) } - var builderOpts []runtime.AppBuilderOption[T] - if sub := viper.Sub("store.options"); sub != nil { - err = sub.Unmarshal(storeOptions) - if err != nil { - panic(err) - } - builderOpts = append(builderOpts, runtime.AppBuilderWithStoreOptions[T](storeOptions)) - } - app.App, err = appBuilder.Build(builderOpts...) + app.App, err = appBuilder.Build() if err != nil { panic(err) } From 8eeb3ff6a9410558b2152baa4fb5761ca46f9d87 Mon Sep 17 00:00:00 2001 From: Akhil Kumar P <36399231+akhilkumarpilli@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:46:04 +0530 Subject: [PATCH 09/10] test: migrate e2e/authz to system tests (#21819) --- tests/e2e/authz/cli_test.go | 20 - tests/e2e/authz/grpc.go | 270 ---------- tests/e2e/authz/tx.go | 923 -------------------------------- tests/systemtests/authz_test.go | 849 +++++++++++++++++++++++++++++ tests/systemtests/bank_test.go | 82 +-- tests/systemtests/rest_cli.go | 29 + tests/systemtests/system.go | 6 + 7 files changed, 913 insertions(+), 1266 deletions(-) delete mode 100644 tests/e2e/authz/cli_test.go delete mode 100644 tests/e2e/authz/grpc.go delete mode 100644 tests/e2e/authz/tx.go create mode 100644 tests/systemtests/authz_test.go create mode 100644 tests/systemtests/rest_cli.go diff --git a/tests/e2e/authz/cli_test.go b/tests/e2e/authz/cli_test.go deleted file mode 100644 index 55348c99bd8f..000000000000 --- a/tests/e2e/authz/cli_test.go +++ /dev/null @@ -1,20 +0,0 @@ -//go:build e2e -// +build e2e - -package authz - -import ( - "testing" - - "github.com/stretchr/testify/suite" - - "cosmossdk.io/simapp" - - "github.com/cosmos/cosmos-sdk/testutil/network" -) - -func TestE2ETestSuite(t *testing.T) { - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - suite.Run(t, NewE2ETestSuite(cfg)) -} diff --git a/tests/e2e/authz/grpc.go b/tests/e2e/authz/grpc.go deleted file mode 100644 index d06c85bb024c..000000000000 --- a/tests/e2e/authz/grpc.go +++ /dev/null @@ -1,270 +0,0 @@ -package authz - -import ( - "fmt" - "time" - - "cosmossdk.io/math" - "cosmossdk.io/x/authz" - "cosmossdk.io/x/authz/client/cli" - authzclitestutil "cosmossdk.io/x/authz/client/testutil" - banktypes "cosmossdk.io/x/bank/types" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/testutil" - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func (s *E2ETestSuite) TestQueryGrantGRPC() { - val := s.network.GetValidators()[0] - grantee := s.grantee[1] - grantsURL := val.GetAPIAddress() + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s&msg_type_url=%s" - testCases := []struct { - name string - url string - expectErr bool - errorMsg string - }{ - { - "fail invalid granter address", - fmt.Sprintf(grantsURL, "invalid_granter", grantee.String(), typeMsgSend), - true, - "decoding bech32 failed: invalid separator index -1: invalid request", - }, - { - "fail invalid grantee address", - fmt.Sprintf(grantsURL, val.GetAddress().String(), "invalid_grantee", typeMsgSend), - true, - "decoding bech32 failed: invalid separator index -1: invalid request", - }, - { - "fail with empty granter", - fmt.Sprintf(grantsURL, "", grantee.String(), typeMsgSend), - true, - "empty address string is not allowed: invalid request", - }, - { - "fail with empty grantee", - fmt.Sprintf(grantsURL, val.GetAddress().String(), "", typeMsgSend), - true, - "empty address string is not allowed: invalid request", - }, - { - "fail invalid msg-type", - fmt.Sprintf(grantsURL, val.GetAddress().String(), grantee.String(), "invalidMsg"), - true, - "authorization not found for invalidMsg type", - }, - { - "valid query", - fmt.Sprintf(grantsURL, val.GetAddress().String(), grantee.String(), typeMsgSend), - false, - "", - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, _ := testutil.GetRequest(tc.url) - require := s.Require() - if tc.expectErr { - require.Contains(string(resp), tc.errorMsg) - } else { - var g authz.QueryGrantsResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(resp, &g) - require.NoError(err) - require.Len(g.Grants, 1) - err = g.Grants[0].UnpackInterfaces(val.GetClientCtx().InterfaceRegistry) - require.NoError(err) - auth, err := g.Grants[0].GetAuthorization() - require.NoError(err) - require.Equal(auth.MsgTypeURL(), banktypes.SendAuthorization{}.MsgTypeURL()) - } - }) - } -} - -func (s *E2ETestSuite) TestQueryGrantsGRPC() { - val := s.network.GetValidators()[0] - grantee := s.grantee[1] - grantsURL := val.GetAPIAddress() + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s" - testCases := []struct { - name string - url string - expectErr bool - errMsg string - preRun func() - postRun func(*authz.QueryGrantsResponse) - }{ - { - "valid query: expect single grant", - fmt.Sprintf(grantsURL, val.GetAddress().String(), grantee.String()), - false, - "", - func() {}, - func(g *authz.QueryGrantsResponse) { - s.Require().Len(g.Grants, 1) - }, - }, - { - "valid query: expect two grants", - fmt.Sprintf(grantsURL, val.GetAddress().String(), grantee.String()), - false, - "", - func() { - _, err := authzclitestutil.CreateGrant(val.GetClientCtx(), []string{ - grantee.String(), - "generic", - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()), - }) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - }, - func(g *authz.QueryGrantsResponse) { - s.Require().Len(g.Grants, 2) - }, - }, - { - "valid query: expect single grant with pagination", - fmt.Sprintf(grantsURL+"&pagination.limit=1", val.GetAddress().String(), grantee.String()), - false, - "", - func() {}, - func(g *authz.QueryGrantsResponse) { - s.Require().Len(g.Grants, 1) - }, - }, - { - "valid query: expect two grants with pagination", - fmt.Sprintf(grantsURL+"&pagination.limit=2", val.GetAddress().String(), grantee.String()), - false, - "", - func() {}, - func(g *authz.QueryGrantsResponse) { - s.Require().Len(g.Grants, 2) - }, - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - tc.preRun() - resp, err := testutil.GetRequest(tc.url) - s.Require().NoError(err) - - if tc.expectErr { - s.Require().Contains(string(resp), tc.errMsg) - } else { - var authorizations authz.QueryGrantsResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(resp, &authorizations) - s.Require().NoError(err) - tc.postRun(&authorizations) - } - }) - } -} - -func (s *E2ETestSuite) TestQueryGranterGrantsGRPC() { - val := s.network.GetValidators()[0] - grantee := s.grantee[1] - require := s.Require() - - testCases := []struct { - name string - url string - expectErr bool - errMsg string - numItems int - }{ - { - "invalid account address", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/granter/%s", val.GetAPIAddress(), "invalid address"), - true, - "decoding bech32 failed", - 0, - }, - { - "no authorizations found", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/granter/%s", val.GetAPIAddress(), grantee.String()), - false, - "", - 0, - }, - { - "valid query", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/granter/%s", val.GetAPIAddress(), val.GetAddress().String()), - false, - "", - 6, - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := testutil.GetRequest(tc.url) - require.NoError(err) - - if tc.expectErr { - require.Contains(string(resp), tc.errMsg) - } else { - var authorizations authz.QueryGranterGrantsResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(resp, &authorizations) - require.NoError(err) - require.Len(authorizations.Grants, tc.numItems) - } - }) - } -} - -func (s *E2ETestSuite) TestQueryGranteeGrantsGRPC() { - val := s.network.GetValidators()[0] - grantee := s.grantee[1] - require := s.Require() - - testCases := []struct { - name string - url string - expectErr bool - errMsg string - numItems int - }{ - { - "invalid account address", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/grantee/%s", val.GetAPIAddress(), "invalid address"), - true, - "decoding bech32 failed", - 0, - }, - { - "no authorizations found", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/grantee/%s", val.GetAPIAddress(), val.GetAddress().String()), - false, - "", - 0, - }, - { - "valid query", - fmt.Sprintf("%s/cosmos/authz/v1beta1/grants/grantee/%s", val.GetAPIAddress(), grantee.String()), - false, - "", - 1, - }, - } - for _, tc := range testCases { - s.Run(tc.name, func() { - resp, err := testutil.GetRequest(tc.url) - require.NoError(err) - - if tc.expectErr { - require.Contains(string(resp), tc.errMsg) - } else { - var authorizations authz.QueryGranteeGrantsResponse - err := val.GetClientCtx().Codec.UnmarshalJSON(resp, &authorizations) - require.NoError(err) - require.Len(authorizations.Grants, tc.numItems) - } - }) - } -} diff --git a/tests/e2e/authz/tx.go b/tests/e2e/authz/tx.go deleted file mode 100644 index bf8757c0777b..000000000000 --- a/tests/e2e/authz/tx.go +++ /dev/null @@ -1,923 +0,0 @@ -package authz - -import ( - "fmt" - "time" - - "github.com/cosmos/gogoproto/proto" - "github.com/stretchr/testify/suite" - - // without this import amino json encoding will fail when resolving any types - _ "cosmossdk.io/api/cosmos/authz/v1beta1" - "cosmossdk.io/math" - "cosmossdk.io/x/authz" - "cosmossdk.io/x/authz/client/cli" - authzclitestutil "cosmossdk.io/x/authz/client/testutil" - bank "cosmossdk.io/x/bank/types" - govcli "cosmossdk.io/x/gov/client/cli" - govtestutil "cosmossdk.io/x/gov/client/testutil" - govv1 "cosmossdk.io/x/gov/types/v1" - govv1beta1 "cosmossdk.io/x/gov/types/v1beta1" - stakingtypes "cosmossdk.io/x/staking/types" - - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/testutil" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" - sdk "github.com/cosmos/cosmos-sdk/types" - authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" -) - -type E2ETestSuite struct { - suite.Suite - - cfg network.Config - network network.NetworkI - grantee []sdk.AccAddress -} - -func NewE2ETestSuite(cfg network.Config) *E2ETestSuite { - return &E2ETestSuite{cfg: cfg} -} - -func (s *E2ETestSuite) SetupSuite() { - s.T().Log("setting up e2e test suite") - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) - - val := s.network.GetValidators()[0] - s.grantee = make([]sdk.AccAddress, 6) - - // Send some funds to the new account. - // Create new account in the keyring. - s.grantee[0] = s.createAccount("grantee1") - s.msgSendExec(s.grantee[0]) - - // create a proposal with deposit - _, err = govtestutil.MsgSubmitLegacyProposal(val.GetClientCtx(), val.GetAddress().String(), - "Text Proposal 1", "Where is the title!?", govv1beta1.ProposalTypeText, - fmt.Sprintf("--%s=%s", govcli.FlagDeposit, sdk.NewCoin(s.cfg.BondDenom, govv1.DefaultMinDepositTokens).String())) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // Create new account in the keyring. - s.grantee[1] = s.createAccount("grantee2") - // Send some funds to the new account. - s.msgSendExec(s.grantee[1]) - - // grant send authorization to grantee2 - out, err := authzclitestutil.CreateGrant(val.GetClientCtx(), []string{ - s.grantee[1].String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()), - }) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - var response sdk.TxResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, 0)) - - // Create new account in the keyring. - s.grantee[2] = s.createAccount("grantee3") - - // grant send authorization to grantee3 - _, err = authzclitestutil.CreateGrant(val.GetClientCtx(), []string{ - s.grantee[2].String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()), - }) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // Create new accounts in the keyring. - s.grantee[3] = s.createAccount("grantee4") - s.msgSendExec(s.grantee[3]) - - s.grantee[4] = s.createAccount("grantee5") - s.grantee[5] = s.createAccount("grantee6") - - // grant send authorization with allow list to grantee4 - out, err = authzclitestutil.CreateGrant(val.GetClientCtx(), - []string{ - s.grantee[3].String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=%s", cli.FlagAllowList, s.grantee[4]), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, 0)) -} - -func (s *E2ETestSuite) createAccount(uid string) sdk.AccAddress { - val := s.network.GetValidators()[0] - // Create new account in the keyring. - k, _, err := val.GetClientCtx().Keyring.NewMnemonic(uid, keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1) - s.Require().NoError(err) - - addr, err := k.GetAddress() - s.Require().NoError(err) - - return addr -} - -func (s *E2ETestSuite) msgSendExec(grantee sdk.AccAddress) { - val := s.network.GetValidators()[0] - // Send some funds to the new account. - - from := val.GetAddress() - coins := sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(200))) - msgSend := &bank.MsgSend{ - FromAddress: from.String(), - ToAddress: grantee.String(), - Amount: coins, - } - - out, err := clitestutil.SubmitTestTx( - val.GetClientCtx(), - msgSend, - from, - clitestutil.TestTxConfig{}, - ) - - s.Require().NoError(err) - s.Require().Contains(out.String(), `"code":0`) - s.Require().NoError(s.network.WaitForNextBlock()) -} - -func (s *E2ETestSuite) TearDownSuite() { - s.T().Log("tearing down e2e test suite") - s.network.Cleanup() -} - -var ( - typeMsgSend = bank.SendAuthorization{}.MsgTypeURL() - typeMsgVote = sdk.MsgTypeURL(&govv1.MsgVote{}) -) - -func (s *E2ETestSuite) TestExecAuthorizationWithExpiration() { - val := s.network.GetValidators()[0] - grantee := s.grantee[0] - tenSeconds := time.Now().Add(time.Second * time.Duration(10)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "generic", - fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, tenSeconds), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - // msg vote - voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1.MsgVote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String()) - execMsg := testutil.WriteToNewTempFile(s.T(), voteTx) - defer execMsg.Close() - - // waiting for authorization to expires - time.Sleep(12 * time.Second) - - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }) - s.Require().NoError(err) - var response sdk.TxResponse - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, response.TxHash, authz.ErrNoAuthorizationFound.ABCICode())) -} - -func (s *E2ETestSuite) TestNewExecGenericAuthorized() { - val := s.network.GetValidators()[0] - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "generic", - fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // msg vote - voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1.MsgVote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String()) - execMsg := testutil.WriteToNewTempFile(s.T(), voteTx) - defer execMsg.Close() - - testCases := []struct { - name string - args []string - respType proto.Message - expectedCode uint32 - expectErr bool - }{ - { - "fail invalid grantee", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, "grantee"), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), - }, - nil, - 0, - true, - }, - { - "fail invalid json path", - []string{ - "/invalid/file.txt", - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - }, - nil, - 0, - true, - }, - { - "valid txn", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - &sdk.TxResponse{}, - 0, - false, - }, - { - "valid tx with amino", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON), - }, - &sdk.TxResponse{}, 0, - false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) - txResp := tc.respType.(*sdk.TxResponse) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), txResp.TxHash, tc.expectedCode)) - } - }) - } -} - -func (s *E2ETestSuite) TestNewExecGrantAuthorized() { - val := s.network.GetValidators()[0] - grantee := s.grantee[0] - grantee1 := s.grantee[2] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "send", - fmt.Sprintf("--%s=12%stoken", cli.FlagSpendLimit, val.GetMoniker()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - from := val.GetAddress() - tokens := sdk.NewCoins( - sdk.NewCoin(fmt.Sprintf("%stoken", val.GetMoniker()), math.NewInt(12)), - ) - msgSend := &bank.MsgSend{ - FromAddress: from.String(), - ToAddress: grantee.String(), - Amount: tokens, - } - normalGeneratedTx, err := clitestutil.SubmitTestTx( - val.GetClientCtx(), - msgSend, - from, - clitestutil.TestTxConfig{ - GenOnly: true, - }, - ) - - s.Require().NoError(err) - execMsg := testutil.WriteToNewTempFile(s.T(), normalGeneratedTx.String()) - defer execMsg.Close() - testCases := []struct { - name string - args []string - expectedCode uint32 - expectErr bool - expectErrMsg string - }{ - { - "valid txn", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - { - "error over grantee doesn't exist on chain", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee1.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - true, - "insufficient funds", // earlier the error was account not found here. - }, - { - "error over spent", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - authz.ErrNoAuthorizationFound.ABCICode(), - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - var response sdk.TxResponse - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - switch { - case tc.expectErrMsg != "": - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().Contains(response.RawLog, tc.expectErrMsg) - - case tc.expectErr: - s.Require().Error(err) - - default: - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, tc.expectedCode)) - } - }) - } -} - -func (s *E2ETestSuite) TestExecSendAuthzWithAllowList() { - val := s.network.GetValidators()[0] - grantee := s.grantee[3] - allowedAddr := s.grantee[4] - notAllowedAddr := s.grantee[5] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "send", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=%s", cli.FlagAllowList, allowedAddr), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - from := val.GetAddress() - tokens := sdk.NewCoins( - sdk.NewCoin("stake", math.NewInt(12)), - ) - msgSend := &bank.MsgSend{ - FromAddress: from.String(), - ToAddress: allowedAddr.String(), - Amount: tokens, - } - - validGeneratedTx, err := clitestutil.SubmitTestTx( - val.GetClientCtx(), - msgSend, - from, - clitestutil.TestTxConfig{ - GenOnly: true, - }, - ) - s.Require().NoError(err) - execMsg := testutil.WriteToNewTempFile(s.T(), validGeneratedTx.String()) - defer execMsg.Close() - - msgSend1 := &bank.MsgSend{ - FromAddress: from.String(), - ToAddress: notAllowedAddr.String(), - Amount: tokens, - } - invalidGeneratedTx, err := clitestutil.SubmitTestTx( - val.GetClientCtx(), - msgSend1, - from, - clitestutil.TestTxConfig{ - GenOnly: true, - }, - ) - s.Require().NoError(err) - execMsg1 := testutil.WriteToNewTempFile(s.T(), invalidGeneratedTx.String()) - defer execMsg1.Close() - - // test sending to allowed address - args := []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - } - var response sdk.TxResponse - cmd := cli.NewCmdExecAuthorization() - out, err := clitestutil.ExecTestCLICmd(val.GetClientCtx(), cmd, args) - s.Require().NoError(err) - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(s.network.WaitForNextBlock()) - - // test sending to not allowed address - args = []string{ - execMsg1.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - } - out, err = clitestutil.ExecTestCLICmd(val.GetClientCtx(), cmd, args) - s.Require().NoError(err) - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(s.network.WaitForNextBlock()) - - // query tx and check result - err = s.network.RetryForBlocks(func() error { - out, err = clitestutil.ExecTestCLICmd(val.GetClientCtx(), authcli.QueryTxCmd(), []string{response.TxHash, fmt.Sprintf("--%s=json", flags.FlagOutput)}) - return err - }, 3) - s.Require().NoError(err) - s.Contains(out.String(), fmt.Sprintf("cannot send to %s address", notAllowedAddr)) -} - -func (s *E2ETestSuite) TestExecDelegateAuthorization() { - val := s.network.GetValidators()[0] - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "delegate", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.GetValAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - tokens := sdk.NewCoins( - sdk.NewCoin("stake", math.NewInt(50)), - ) - - delegateTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgDelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String(), val.GetValAddress().String(), - tokens.GetDenomByIndex(0), tokens[0].Amount) - execMsg := testutil.WriteToNewTempFile(s.T(), delegateTx) - defer execMsg.Close() - - testCases := []struct { - name string - args []string - expectedCode uint32 - expectErr bool - errMsg string - }{ - { - "valid txn: (delegate half tokens)", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - { - "valid txn: (delegate remaining half tokens)", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - { - "failed with error no authorization found", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - authz.ErrNoAuthorizationFound.ABCICode(), - false, - authz.ErrNoAuthorizationFound.Error(), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errMsg) - } else { - var response sdk.TxResponse - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, tc.expectedCode)) - } - }) - } - - // test delegate no spend-limit - _, err = authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "delegate", - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.GetValAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - tokens = sdk.NewCoins( - sdk.NewCoin("stake", math.NewInt(50)), - ) - - delegateTx = fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgDelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String(), val.GetValAddress().String(), - tokens.GetDenomByIndex(0), tokens[0].Amount) - execMsg = testutil.WriteToNewTempFile(s.T(), delegateTx) - defer execMsg.Close() - - testCases = []struct { - name string - args []string - expectedCode uint32 - expectErr bool - errMsg string - }{ - { - "valid txn", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errMsg) - } else { - var response sdk.TxResponse - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, tc.expectedCode)) - } - }) - } - - // test delegating to denied validator - _, err = authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "delegate", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", cli.FlagDenyValidators, val.GetValAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - args := []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - } - cmd := cli.NewCmdExecAuthorization() - out, err := clitestutil.ExecTestCLICmd(val.GetClientCtx(), cmd, args) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - var response sdk.TxResponse - s.Require().NoError(val.GetClientCtx().Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - - // query tx and check result - err = s.network.RetryForBlocks(func() error { - out, err = clitestutil.ExecTestCLICmd(val.GetClientCtx(), authcli.QueryTxCmd(), []string{response.TxHash, fmt.Sprintf("--%s=json", flags.FlagOutput)}) - return err - }, 3) - s.Require().NoError(err) - s.Contains(out.String(), fmt.Sprintf("cannot delegate/undelegate to %s validator", val.GetValAddress().String())) -} - -func (s *E2ETestSuite) TestExecUndelegateAuthorization() { - val := s.network.GetValidators()[0] - grantee := s.grantee[0] - twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() - - // granting undelegate msg authorization - _, err := authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "unbond", - fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.GetValAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - // delegating stakes to validator - msg := &stakingtypes.MsgDelegate{ - DelegatorAddress: val.GetAddress().String(), - ValidatorAddress: val.GetValAddress().String(), - Amount: sdk.NewCoin("stake", math.NewInt(100)), - } - - _, err = clitestutil.SubmitTestTx(val.GetClientCtx(), msg, val.GetAddress(), clitestutil.TestTxConfig{}) - - s.Require().NoError(err) - - tokens := sdk.NewCoins( - sdk.NewCoin("stake", math.NewInt(50)), - ) - - undelegateTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgUndelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String(), val.GetValAddress().String(), - tokens.GetDenomByIndex(0), tokens[0].Amount) - execMsg := testutil.WriteToNewTempFile(s.T(), undelegateTx) - defer execMsg.Close() - - testCases := []struct { - name string - args []string - expectedCode uint32 - expectErr bool - errMsg string - }{ - { - "valid txn: (undelegate half tokens)", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - { - "valid txn: (undelegate remaining half tokens)", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - { - "failed with error no authorization found", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - authz.ErrNoAuthorizationFound.ABCICode(), - false, - authz.ErrNoAuthorizationFound.Error(), - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errMsg) - } else { - var response sdk.TxResponse - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, tc.expectedCode)) - } - }) - } - - // grant undelegate authorization without limit - _, err = authzclitestutil.CreateGrant( - val.GetClientCtx(), - []string{ - grantee.String(), - "unbond", - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.GetAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), - fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, val.GetValAddress().String()), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - }, - ) - s.Require().NoError(err) - s.Require().NoError(s.network.WaitForNextBlock()) - - tokens = sdk.NewCoins( - sdk.NewCoin("stake", math.NewInt(50)), - ) - - undelegateTx = fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.staking.v1beta1.MsgUndelegate","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%s"}}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val.GetAddress().String(), val.GetValAddress().String(), - tokens.GetDenomByIndex(0), tokens[0].Amount) - execMsg = testutil.WriteToNewTempFile(s.T(), undelegateTx) - defer execMsg.Close() - - testCases = []struct { - name string - args []string - expectedCode uint32 - expectErr bool - errMsg string - }{ - { - "valid txn", - []string{ - execMsg.Name(), - fmt.Sprintf("--%s=%s", flags.FlagGas, "250000"), - fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()), - fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()), - fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), - }, - 0, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - cmd := cli.NewCmdExecAuthorization() - clientCtx := val.GetClientCtx() - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errMsg) - } else { - var response sdk.TxResponse - s.Require().NoError(err) - s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String()) - s.Require().NoError(clitestutil.CheckTxCode(s.network, val.GetClientCtx(), response.TxHash, tc.expectedCode)) - } - }) - } -} diff --git a/tests/systemtests/authz_test.go b/tests/systemtests/authz_test.go new file mode 100644 index 000000000000..c411ad20d36e --- /dev/null +++ b/tests/systemtests/authz_test.go @@ -0,0 +1,849 @@ +//go:build system_test + +package systemtests + +import ( + "fmt" + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" +) + +const ( + msgSendTypeURL = `/cosmos.bank.v1beta1.MsgSend` + msgDelegateTypeURL = `/cosmos.staking.v1beta1.MsgDelegate` + msgVoteTypeURL = `/cosmos.gov.v1.MsgVote` + msgUndelegateTypeURL = `/cosmos.staking.v1beta1.MsgUndelegate` + msgRedelegateTypeURL = `/cosmos.staking.v1beta1.MsgBeginRedelegate` + sendAuthzTypeURL = `/cosmos.bank.v1beta1.SendAuthorization` + genericAuthzTypeURL = `/cosmos.authz.v1beta1.GenericAuthorization` + testDenom = "stake" +) + +func TestAuthzGrantTxCmd(t *testing.T) { + // scenario: test authz grant command + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address which will be used as granter + granterAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, granterAddr) + + // add grantee keys which will be used for each valid transaction + grantee1Addr := cli.AddKey("grantee1") + grantee2Addr := cli.AddKey("grantee2") + require.NotEqual(t, granterAddr, grantee2Addr) + grantee3Addr := cli.AddKey("grantee3") + require.NotEqual(t, granterAddr, grantee3Addr) + grantee4Addr := cli.AddKey("grantee4") + require.NotEqual(t, granterAddr, grantee4Addr) + grantee5Addr := cli.AddKey("grantee5") + require.NotEqual(t, granterAddr, grantee5Addr) + grantee6Addr := cli.AddKey("grantee6") + require.NotEqual(t, granterAddr, grantee6Addr) + + sut.StartChain(t) + + // query validator operator address + rsp := cli.CustomQuery("q", "staking", "validators") + valOperAddr := gjson.Get(rsp, "validators.#.operator_address").Array()[0].String() + + grantCmdArgs := []string{"tx", "authz", "grant", "--from", granterAddr} + expirationTime := time.Now().Add(time.Hour).Unix() + + // test grant command + testCases := []struct { + name string + grantee string + cmdArgs []string + expErrMsg string + queryTx bool + }{ + { + "invalid authorization type", + grantee1Addr, + []string{"spend"}, + "invalid authorization type", + false, + }, + { + "send authorization without spend-limit", + grantee1Addr, + []string{"send"}, + "spend-limit should be greater than zero", + false, + }, + { + "generic authorization without msg type", + grantee1Addr, + []string{"generic"}, + "msg type cannot be empty", + true, + }, + { + "delegate authorization without allow or deny list", + grantee1Addr, + []string{"delegate"}, + "both allowed & deny list cannot be empty", + false, + }, + { + "delegate authorization with invalid allowed validator address", + grantee1Addr, + []string{"delegate", "--allowed-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "delegate authorization with invalid deny validator address", + grantee1Addr, + []string{"delegate", "--deny-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "unbond authorization without allow or deny list", + grantee1Addr, + []string{"unbond"}, + "both allowed & deny list cannot be empty", + false, + }, + { + "unbond authorization with invalid allowed validator address", + grantee1Addr, + []string{"unbond", "--allowed-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "unbond authorization with invalid deny validator address", + grantee1Addr, + []string{"unbond", "--deny-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "redelegate authorization without allow or deny list", + grantee1Addr, + []string{"redelegate"}, + "both allowed & deny list cannot be empty", + false, + }, + { + "redelegate authorization with invalid allowed validator address", + grantee1Addr, + []string{"redelegate", "--allowed-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "redelegate authorization with invalid deny validator address", + grantee1Addr, + []string{"redelegate", "--deny-validators=invalid"}, + "decoding bech32 failed", + false, + }, + { + "valid send authorization", + grantee1Addr, + []string{"send", "--spend-limit=1000" + testDenom}, + "", + false, + }, + { + "valid send authorization with expiration", + grantee2Addr, + []string{"send", "--spend-limit=1000" + testDenom, fmt.Sprintf("--expiration=%d", expirationTime)}, + "", + false, + }, + { + "valid generic authorization", + grantee3Addr, + []string{"generic", "--msg-type=" + msgVoteTypeURL}, + "", + false, + }, + { + "valid delegate authorization", + grantee4Addr, + []string{"delegate", "--allowed-validators=" + valOperAddr}, + "", + false, + }, + { + "valid unbond authorization", + grantee5Addr, + []string{"unbond", "--deny-validators=" + valOperAddr}, + "", + false, + }, + { + "valid redelegate authorization", + grantee6Addr, + []string{"redelegate", "--allowed-validators=" + valOperAddr}, + "", + false, + }, + } + + grantsCount := 0 + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cmd := append(append(grantCmdArgs, tc.grantee), tc.cmdArgs...) + if tc.expErrMsg != "" { + if tc.queryTx { + rsp := cli.Run(cmd...) + RequireTxFailure(t, rsp) + require.Contains(t, rsp, tc.expErrMsg) + } else { + assertErr := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { + require.Len(t, gotOutputs, 1) + output := gotOutputs[0].(string) + require.Contains(t, output, tc.expErrMsg) + return false + } + _ = cli.WithRunErrorMatcher(assertErr).Run(cmd...) + } + return + } + rsp := cli.RunAndWait(cmd...) + RequireTxSuccess(t, rsp) + + // query granter-grantee grants + resp := cli.CustomQuery("q", "authz", "grants", granterAddr, tc.grantee) + grants := gjson.Get(resp, "grants").Array() + // check grants length equal to 1 to confirm grant created successfully + require.Len(t, grants, 1) + grantsCount++ + }) + } + + // query grants-by-granter + resp := cli.CustomQuery("q", "authz", "grants-by-granter", granterAddr) + grants := gjson.Get(resp, "grants").Array() + require.Len(t, grants, grantsCount) +} + +func TestAuthzExecSendAuthorization(t *testing.T) { + // scenario: test authz exec send authorization + // given a running chain + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + // get validator address which will be used as granter + granterAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, granterAddr) + + // add grantee keys which will be used for each valid transaction + granteeAddr := cli.AddKey("grantee") + require.NotEqual(t, granterAddr, granteeAddr) + allowedAddr := cli.AddKey("allowed") + require.NotEqual(t, granteeAddr, allowedAddr) + notAllowedAddr := cli.AddKey("notAllowed") + require.NotEqual(t, granteeAddr, notAllowedAddr) + newAccount := cli.AddKey("newAccount") + require.NotEqual(t, granteeAddr, newAccount) + + var initialAmount int64 = 10000000 + initialBalance := fmt.Sprintf("%d%s", initialAmount, testDenom) + sut.ModifyGenesisCLI(t, + []string{"genesis", "add-genesis-account", granteeAddr, initialBalance}, + []string{"genesis", "add-genesis-account", allowedAddr, initialBalance}, + []string{"genesis", "add-genesis-account", newAccount, initialBalance}, + ) + sut.StartChain(t) + + // query balances + granterBal := cli.QueryBalance(granterAddr, testDenom) + granteeBal := cli.QueryBalance(granteeAddr, testDenom) + require.Equal(t, initialAmount, granteeBal) + allowedAddrBal := cli.QueryBalance(allowedAddr, testDenom) + require.Equal(t, initialAmount, allowedAddrBal) + + var spendLimitAmount int64 = 1000 + expirationTime := time.Now().Add(time.Second * 10).Unix() + + // test exec send authorization + + // create send authorization grant + rsp := cli.RunAndWait("tx", "authz", "grant", granteeAddr, "send", + "--spend-limit="+fmt.Sprintf("%d%s", spendLimitAmount, testDenom), + "--allow-list="+allowedAddr, + "--expiration="+fmt.Sprintf("%d", expirationTime), + "--fees=1"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + // reduce fees of above tx from granter balance + granterBal-- + + testCases := []struct { + name string + grantee string + toAddr string + amount int64 + expErrMsg string + }{ + { + "valid exec transaction", + granteeAddr, + allowedAddr, + 20, + "", + }, + { + "send to not allowed address", + granteeAddr, + notAllowedAddr, + 10, + "cannot send to", + }, + { + "amount greater than spend limit", + granteeAddr, + allowedAddr, + spendLimitAmount + 5, + "requested amount is more than spend limit", + }, + { + "no grant found", + newAccount, + granteeAddr, + 20, + "authorization not found", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // msg send + cmd := msgSendExec(t, granterAddr, tc.grantee, tc.toAddr, testDenom, tc.amount) + if tc.expErrMsg != "" { + rsp := cli.Run(cmd...) + RequireTxFailure(t, rsp) + require.Contains(t, rsp, tc.expErrMsg) + return + } + rsp := cli.RunAndWait(cmd...) + RequireTxSuccess(t, rsp) + + // check granter balance equals to granterBal - transferredAmount + expGranterBal := granterBal - tc.amount + require.Equal(t, expGranterBal, cli.QueryBalance(granterAddr, testDenom)) + granterBal = expGranterBal + + // check allowed addr balance equals to allowedAddrBal + transferredAmount + expAllowAddrBal := allowedAddrBal + tc.amount + require.Equal(t, expAllowAddrBal, cli.QueryBalance(allowedAddr, testDenom)) + allowedAddrBal = expAllowAddrBal + }) + } + + // test grant expiry + time.Sleep(time.Second * 10) + + execSendCmd := msgSendExec(t, granterAddr, granteeAddr, allowedAddr, testDenom, 10) + rsp = cli.Run(execSendCmd...) + RequireTxFailure(t, rsp) + require.Contains(t, rsp, "authorization not found") +} + +func TestAuthzExecGenericAuthorization(t *testing.T) { + // scenario: test authz exec generic authorization + // given a running chain + + cli, granterAddr, granteeAddr := setupChain(t) + + allowedAddr := cli.AddKey("allowedAddr") + require.NotEqual(t, granterAddr, allowedAddr) + + // query balances + granterBal := cli.QueryBalance(granterAddr, testDenom) + + expirationTime := time.Now().Add(time.Second * 5).Unix() + execSendCmd := msgSendExec(t, granterAddr, granteeAddr, allowedAddr, testDenom, 10) + + // create generic authorization grant + rsp := cli.RunAndWait("tx", "authz", "grant", granteeAddr, "generic", + "--msg-type="+msgSendTypeURL, + "--expiration="+fmt.Sprintf("%d", expirationTime), + "--fees=1"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + granterBal-- + + rsp = cli.RunAndWait(execSendCmd...) + RequireTxSuccess(t, rsp) + // check granter balance equals to granterBal - transferredAmount + expGranterBal := granterBal - 10 + require.Equal(t, expGranterBal, cli.QueryBalance(granterAddr, testDenom)) + + time.Sleep(time.Second * 5) + + // check grants after expiration + resp := cli.CustomQuery("q", "authz", "grants", granterAddr, granteeAddr) + grants := gjson.Get(resp, "grants").Array() + require.Len(t, grants, 0) +} + +func TestAuthzExecDelegateAuthorization(t *testing.T) { + // scenario: test authz exec delegate authorization + // given a running chain + + cli, granterAddr, granteeAddr := setupChain(t) + + // query balances + granterBal := cli.QueryBalance(granterAddr, testDenom) + + // query validator operator address + rsp := cli.CustomQuery("q", "staking", "validators") + validators := gjson.Get(rsp, "validators.#.operator_address").Array() + require.GreaterOrEqual(t, len(validators), 2) + val1Addr := validators[0].String() + val2Addr := validators[1].String() + + var spendLimitAmount int64 = 1000 + require.Greater(t, granterBal, spendLimitAmount) + + rsp = cli.RunAndWait("tx", "authz", "grant", granteeAddr, "delegate", + "--spend-limit="+fmt.Sprintf("%d%s", spendLimitAmount, testDenom), + "--allowed-validators="+val1Addr, + "--fees=1"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + // reduce fees of above tx from granter balance + granterBal-- + + delegateTestCases := []struct { + name string + grantee string + valAddr string + amount int64 + expErrMsg string + }{ + { + "valid txn: (delegate half tokens)", + granteeAddr, + val1Addr, + spendLimitAmount / 2, + "", + }, + { + "amount greater than spend limit", + granteeAddr, + val1Addr, + spendLimitAmount + 5, + "negative coin amount", + }, + { + "delegate to not allowed address", + granteeAddr, + val2Addr, + 10, + "cannot delegate", + }, + { + "valid txn: (delegate remaining half tokens)", + granteeAddr, + val1Addr, + spendLimitAmount / 2, + "", + }, + { + "no authorization found as grant prunes", + granteeAddr, + val1Addr, + spendLimitAmount / 2, + "authorization not found", + }, + } + + execCmdArgs := []string{"tx", "authz", "exec"} + + for _, tc := range delegateTestCases { + t.Run(tc.name, func(t *testing.T) { + delegateTx := fmt.Sprintf(`{"@type":"%s","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%d"}}`, + msgDelegateTypeURL, granterAddr, tc.valAddr, testDenom, tc.amount) + execMsg := WriteToTempJSONFile(t, delegateTx) + + cmd := append(append(execCmdArgs, execMsg.Name()), "--from="+tc.grantee) + if tc.expErrMsg != "" { + rsp := cli.Run(cmd...) + RequireTxFailure(t, rsp) + require.Contains(t, rsp, tc.expErrMsg) + return + } + rsp := cli.RunAndWait(cmd...) + RequireTxSuccess(t, rsp) + + // check granter balance equals to granterBal - transferredAmount + expGranterBal := granterBal - tc.amount + require.Equal(t, expGranterBal, cli.QueryBalance(granterAddr, testDenom)) + granterBal = expGranterBal + }) + } +} + +func TestAuthzExecUndelegateAuthorization(t *testing.T) { + // scenario: test authz exec undelegate authorization + // given a running chain + + cli, granterAddr, granteeAddr := setupChain(t) + + // query validator operator address + rsp := cli.CustomQuery("q", "staking", "validators") + validators := gjson.Get(rsp, "validators.#.operator_address").Array() + require.GreaterOrEqual(t, len(validators), 2) + val1Addr := validators[0].String() + val2Addr := validators[1].String() + + // delegate some tokens + rsp = cli.RunAndWait("tx", "staking", "delegate", val1Addr, "10000"+testDenom, "--from="+granterAddr) + RequireTxSuccess(t, rsp) + + // query delegated tokens count + resp := cli.CustomQuery("q", "staking", "delegation", granterAddr, val1Addr) + delegatedAmount := gjson.Get(resp, "delegation_response.balance.amount").Int() + + rsp = cli.RunAndWait("tx", "authz", "grant", granteeAddr, "unbond", + "--allowed-validators="+val1Addr, + "--fees=1"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + + undelegateTestCases := []struct { + name string + grantee string + valAddr string + amount int64 + expErrMsg string + }{ + { + "valid transaction", + granteeAddr, + val1Addr, + 10, + "", + }, + { + "undelegate to not allowed address", + granteeAddr, + val2Addr, + 10, + "cannot delegate/undelegate", + }, + } + + for _, tc := range undelegateTestCases { + t.Run(tc.name, func(t *testing.T) { + undelegateTx := fmt.Sprintf(`{"@type":"%s","delegator_address":"%s","validator_address":"%s","amount":{"denom":"%s","amount":"%d"}}`, + msgUndelegateTypeURL, granterAddr, tc.valAddr, testDenom, tc.amount) + execMsg := WriteToTempJSONFile(t, undelegateTx) + + cmd := []string{"tx", "authz", "exec", execMsg.Name(), "--from=" + tc.grantee} + if tc.expErrMsg != "" { + rsp := cli.Run(cmd...) + RequireTxFailure(t, rsp) + require.Contains(t, rsp, tc.expErrMsg) + return + } + rsp := cli.RunAndWait(cmd...) + RequireTxSuccess(t, rsp) + + // query delegation and check balance reduced + expectedAmount := delegatedAmount - tc.amount + resp = cli.CustomQuery("q", "staking", "delegation", granterAddr, val1Addr) + delegatedAmount = gjson.Get(resp, "delegation_response.balance.amount").Int() + require.Equal(t, expectedAmount, delegatedAmount) + }) + } + + // revoke existing grant + rsp = cli.RunAndWait("tx", "authz", "revoke", granteeAddr, msgUndelegateTypeURL, "--from", granterAddr) + RequireTxSuccess(t, rsp) + + // check grants between granter and grantee after revoking + resp = cli.CustomQuery("q", "authz", "grants", granterAddr, granteeAddr) + grants := gjson.Get(resp, "grants").Array() + require.Len(t, grants, 0) +} + +func TestAuthzExecRedelegateAuthorization(t *testing.T) { + // scenario: test authz exec redelegate authorization + // given a running chain + + cli, granterAddr, granteeAddr := setupChain(t) + + // query validator operator address + rsp := cli.CustomQuery("q", "staking", "validators") + validators := gjson.Get(rsp, "validators.#.operator_address").Array() + require.GreaterOrEqual(t, len(validators), 2) + val1Addr := validators[0].String() + val2Addr := validators[1].String() + + // delegate some tokens + rsp = cli.RunAndWait("tx", "staking", "delegate", val1Addr, "10000"+testDenom, "--from="+granterAddr) + RequireTxSuccess(t, rsp) + + // test exec redelegate authorization + rsp = cli.RunAndWait("tx", "authz", "grant", granteeAddr, "redelegate", + fmt.Sprintf("--allowed-validators=%s,%s", val1Addr, val2Addr), + "--fees=1"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + + var redelegationAmount int64 = 10 + + redelegateTx := fmt.Sprintf(`{"@type":"%s","delegator_address":"%s","validator_src_address":"%s","validator_dst_address":"%s","amount":{"denom":"%s","amount":"%d"}}`, + msgRedelegateTypeURL, granterAddr, val1Addr, val2Addr, testDenom, redelegationAmount) + execMsg := WriteToTempJSONFile(t, redelegateTx) + + redelegateCmd := []string{"tx", "authz", "exec", execMsg.Name(), "--from=" + granteeAddr, "--gas=auto"} + rsp = cli.RunAndWait(redelegateCmd...) + RequireTxSuccess(t, rsp) + + // query new delegation and check balance increased + resp := cli.CustomQuery("q", "staking", "delegation", granterAddr, val2Addr) + delegatedAmount := gjson.Get(resp, "delegation_response.balance.amount").Int() + require.GreaterOrEqual(t, delegatedAmount, redelegationAmount) + + // revoke all existing grants + rsp = cli.RunAndWait("tx", "authz", "revoke-all", "--from", granterAddr) + RequireTxSuccess(t, rsp) + + // check grants after revoking + resp = cli.CustomQuery("q", "authz", "grants-by-granter", granterAddr) + grants := gjson.Get(resp, "grants").Array() + require.Len(t, grants, 0) +} + +func TestAuthzGRPCQueries(t *testing.T) { + // scenario: test authz grpc gateway queries + // given a running chain + + cli, granterAddr, grantee1Addr := setupChain(t) + + grantee2Addr := cli.AddKey("grantee2") + require.NotEqual(t, granterAddr, grantee2Addr) + require.NotEqual(t, grantee1Addr, grantee2Addr) + + // create few grants + rsp := cli.RunAndWait("tx", "authz", "grant", grantee1Addr, "send", + "--spend-limit=10000"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + grant1 := fmt.Sprintf(`"authorization":{"@type":"%s","spend_limit":[{"denom":"%s","amount":"10000"}],"allow_list":[]},"expiration":null`, sendAuthzTypeURL, testDenom) + + rsp = cli.RunAndWait("tx", "authz", "grant", grantee2Addr, "send", + "--spend-limit=1000"+testDenom, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + grant2 := fmt.Sprintf(`"authorization":{"@type":"%s","spend_limit":[{"denom":"%s","amount":"1000"}],"allow_list":[]},"expiration":null`, sendAuthzTypeURL, testDenom) + + rsp = cli.RunAndWait("tx", "authz", "grant", grantee2Addr, "generic", + "--msg-type="+msgVoteTypeURL, + "--from", granterAddr) + RequireTxSuccess(t, rsp) + grant3 := fmt.Sprintf(`"authorization":{"@type":"%s","msg":"%s"},"expiration":null`, genericAuthzTypeURL, msgVoteTypeURL) + + rsp = cli.RunAndWait("tx", "authz", "grant", grantee2Addr, "generic", + "--msg-type="+msgDelegateTypeURL, + "--from", grantee1Addr) + RequireTxSuccess(t, rsp) + grant4 := fmt.Sprintf(`"authorization":{"@type":"%s","msg":"%s"},"expiration":null`, genericAuthzTypeURL, msgDelegateTypeURL) + + baseurl := sut.APIAddress() + + // test query grant grpc endpoint + grantURL := baseurl + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s&msg_type_url=%s" + + bech32FailOutput := `{"code":2, "message":"decoding bech32 failed: invalid separator index -1", "details":[]}` + emptyStrOutput := `{"code":2, "message":"empty address string is not allowed", "details":[]}` + invalidMsgTypeOutput := `{"code":2, "message":"codespace authz code 2: authorization not found: authorization not found for invalidMsg type", "details":[]}` + expGrantOutput := fmt.Sprintf(`{"grants":[{%s}],"pagination":null}`, grant1) + + grantTestCases := []GRPCTestCase{ + { + "invalid granter address", + fmt.Sprintf(grantURL, "invalid_granter", grantee1Addr, msgSendTypeURL), + bech32FailOutput, + }, + { + "invalid grantee address", + fmt.Sprintf(grantURL, granterAddr, "invalid_grantee", msgSendTypeURL), + bech32FailOutput, + }, + { + "with empty granter", + fmt.Sprintf(grantURL, "", grantee1Addr, msgSendTypeURL), + emptyStrOutput, + }, + { + "with empty grantee", + fmt.Sprintf(grantURL, granterAddr, "", msgSendTypeURL), + emptyStrOutput, + }, + { + "invalid msg-type", + fmt.Sprintf(grantURL, granterAddr, grantee1Addr, "invalidMsg"), + invalidMsgTypeOutput, + }, + { + "valid grant query", + fmt.Sprintf(grantURL, granterAddr, grantee1Addr, msgSendTypeURL), + expGrantOutput, + }, + } + + RunGRPCQueries(t, grantTestCases) + + // test query grants grpc endpoint + grantsURL := baseurl + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s" + + grantsTestCases := []GRPCTestCase{ + { + "expect single grant", + fmt.Sprintf(grantsURL, granterAddr, grantee1Addr), + fmt.Sprintf(`{"grants":[{%s}],"pagination":{"next_key":null,"total":"1"}}`, grant1), + }, + { + "expect two grants", + fmt.Sprintf(grantsURL, granterAddr, grantee2Addr), + fmt.Sprintf(`{"grants":[{%s},{%s}],"pagination":{"next_key":null,"total":"2"}}`, grant2, grant3), + }, + { + "expect single grant with pagination", + fmt.Sprintf(grantsURL+"&pagination.limit=1", granterAddr, grantee2Addr), + fmt.Sprintf(`{"grants":[{%s}],"pagination":{"next_key":"L2Nvc21vcy5nb3YudjEuTXNnVm90ZQ==","total":"0"}}`, grant2), + }, + { + "expect single grant with pagination limit and offset", + fmt.Sprintf(grantsURL+"&pagination.limit=1&pagination.offset=1", granterAddr, grantee2Addr), + fmt.Sprintf(`{"grants":[{%s}],"pagination":{"next_key":null,"total":"0"}}`, grant3), + }, + { + "expect two grants with pagination", + fmt.Sprintf(grantsURL+"&pagination.limit=2", granterAddr, grantee2Addr), + fmt.Sprintf(`{"grants":[{%s},{%s}],"pagination":{"next_key":null,"total":"0"}}`, grant2, grant3), + }, + } + + RunGRPCQueries(t, grantsTestCases) + + // test query grants by granter grpc endpoint + grantsByGranterURL := baseurl + "/cosmos/authz/v1beta1/grants/granter/%s" + decodingFailedOutput := `{"code":2, "message":"decoding bech32 failed: invalid character in string: ' '", "details":[]}` + noAuthorizationsOutput := `{"grants":[],"pagination":{"next_key":null,"total":"0"}}` + granterQueryOutput := fmt.Sprintf(`{"grants":[{"granter":"%s","grantee":"%s",%s}],"pagination":{"next_key":null,"total":"1"}}`, + grantee1Addr, grantee2Addr, grant4) + + granterTestCases := []GRPCTestCase{ + { + "invalid granter account address", + fmt.Sprintf(grantsByGranterURL, "invalid address"), + decodingFailedOutput, + }, + { + "no authorizations found from granter", + fmt.Sprintf(grantsByGranterURL, grantee2Addr), + noAuthorizationsOutput, + }, + { + "valid granter query", + fmt.Sprintf(grantsByGranterURL, grantee1Addr), + granterQueryOutput, + }, + } + + RunGRPCQueries(t, granterTestCases) + + // test query grants by grantee grpc endpoint + grantsByGranteeURL := baseurl + "/cosmos/authz/v1beta1/grants/grantee/%s" + grantee1GrantsOutput := fmt.Sprintf(`{"grants":[{"granter":"%s","grantee":"%s",%s}],"pagination":{"next_key":null,"total":"1"}}`, granterAddr, grantee1Addr, grant1) + + granteeTestCases := []GRPCTestCase{ + { + "invalid grantee account address", + fmt.Sprintf(grantsByGranteeURL, "invalid address"), + decodingFailedOutput, + }, + { + "no authorizations found from grantee", + fmt.Sprintf(grantsByGranteeURL, granterAddr), + noAuthorizationsOutput, + }, + { + "valid grantee query", + fmt.Sprintf(grantsByGranteeURL, grantee1Addr), + grantee1GrantsOutput, + }, + } + + RunGRPCQueries(t, granteeTestCases) +} + +func setupChain(t *testing.T) (*CLIWrapper, string, string) { + t.Helper() + + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + + require.GreaterOrEqual(t, cli.nodesCount, 2) + + // get validators' address which will be used as granter and grantee + granterAddr := cli.GetKeyAddr("node0") + require.NotEmpty(t, granterAddr) + granteeAddr := cli.GetKeyAddr("node1") + require.NotEmpty(t, granteeAddr) + + sut.StartChain(t) + + return cli, granterAddr, granteeAddr +} + +func msgSendExec(t *testing.T, granter, grantee, toAddr, denom string, amount int64) []string { + t.Helper() + + bankTx := fmt.Sprintf(`{ + "@type": "%s", + "from_address": "%s", + "to_address": "%s", + "amount": [ + { + "denom": "%s", + "amount": "%d" + } + ] + }`, msgSendTypeURL, granter, toAddr, denom, amount) + execMsg := WriteToTempJSONFile(t, bankTx) + + execSendCmd := []string{"tx", "authz", "exec", execMsg.Name(), "--from=" + grantee} + return execSendCmd +} + +// Write the given string to a new temporary json file. +// Returns an file for the test to use. +func WriteToTempJSONFile(tb testing.TB, s string) *os.File { + tb.Helper() + + tmpFile, err := os.CreateTemp(tb.TempDir(), "test-*.json") + require.NoError(tb, err) + + // Write to the temporary file + _, err = tmpFile.WriteString(s) + require.NoError(tb, err) + + // Close the file after writing + err = tmpFile.Close() + require.NoError(tb, err) + + return tmpFile +} diff --git a/tests/systemtests/bank_test.go b/tests/systemtests/bank_test.go index 2e028728566a..255e4bae9662 100644 --- a/tests/systemtests/bank_test.go +++ b/tests/systemtests/bank_test.go @@ -23,7 +23,7 @@ func TestBankSendTxCmd(t *testing.T) { cli := NewCLIWrapper(t, sut, verbose) // get validator address - valAddr := gjson.Get(cli.Keys("keys", "list"), "1.address").String() + valAddr := cli.GetKeyAddr("node0") require.NotEmpty(t, valAddr) // add new key @@ -131,28 +131,24 @@ func TestBankMultiSendTxCmd(t *testing.T) { testCases := []struct { name string cmdArgs []string - expectErr bool expectedCode uint32 expErrMsg string }{ { "valid transaction", append(multiSendCmdArgs, "--fees=1stake"), - false, 0, "", }, { "not enough arguments", []string{"tx", "bank", "multi-send", account1Addr, account2Addr, "1000stake", "--from=" + account1Addr}, - true, 0, "only received 3", }, { "chain-id shouldn't be used with offline and generate-only flags", append(multiSendCmdArgs, "--generate-only", "--offline", "-a=0", "-s=4"), - true, 0, "chain ID cannot be used", }, @@ -160,7 +156,7 @@ func TestBankMultiSendTxCmd(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - if tc.expectErr { + if tc.expErrMsg != "" { assertErr := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { require.Len(t, gotOutputs, 1) output := gotOutputs[0].(string) @@ -173,24 +169,24 @@ func TestBankMultiSendTxCmd(t *testing.T) { return false // always abort } _ = cli.WithRunErrorMatcher(assertErr).Run(tc.cmdArgs...) - } else { - rsp := cli.Run(tc.cmdArgs...) - txResult, found := cli.AwaitTxCommitted(rsp) - require.True(t, found) - RequireTxSuccess(t, txResult) - // check account1 balance equals to account1Bal - transferredAmount*no_of_accounts - fees - expAcc1Balance := account1Bal - (1000 * 2) - 1 - require.Equal(t, expAcc1Balance, cli.QueryBalance(account1Addr, denom)) - account1Bal = expAcc1Balance - // check account2 balance equals to account2Bal + transferredAmount - expAcc2Balance := account2Bal + 1000 - require.Equal(t, expAcc2Balance, cli.QueryBalance(account2Addr, denom)) - account2Bal = expAcc2Balance - // check account3 balance equals to account3Bal + transferredAmount - expAcc3Balance := account3Bal + 1000 - require.Equal(t, expAcc3Balance, cli.QueryBalance(account3Addr, denom)) - account3Bal = expAcc3Balance + return } + rsp := cli.Run(tc.cmdArgs...) + txResult, found := cli.AwaitTxCommitted(rsp) + require.True(t, found) + RequireTxSuccess(t, txResult) + // check account1 balance equals to account1Bal - transferredAmount*no_of_accounts - fees + expAcc1Balance := account1Bal - (1000 * 2) - 1 + require.Equal(t, expAcc1Balance, cli.QueryBalance(account1Addr, denom)) + account1Bal = expAcc1Balance + // check account2 balance equals to account2Bal + transferredAmount + expAcc2Balance := account2Bal + 1000 + require.Equal(t, expAcc2Balance, cli.QueryBalance(account2Addr, denom)) + account2Bal = expAcc2Balance + // check account3 balance equals to account3Bal + transferredAmount + expAcc3Balance := account3Bal + 1000 + require.Equal(t, expAcc3Balance, cli.QueryBalance(account3Addr, denom)) + account3Bal = expAcc3Balance }) } } @@ -224,7 +220,7 @@ func TestBankGRPCQueries(t *testing.T) { // start chain sut.StartChain(t) - baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) + baseurl := sut.APIAddress() // test supply grpc endpoint supplyUrl := baseurl + "/cosmos/bank/v1beta1/supply" @@ -283,45 +279,31 @@ func TestBankGRPCQueries(t *testing.T) { // test denom metadata endpoint denomMetadataUrl := baseurl + "/cosmos/bank/v1beta1/denoms_metadata" - dmTestCases := []struct { - name string - url string - expOut string - }{ + dmTestCases := []GRPCTestCase{ { "test GRPC client metadata", denomMetadataUrl, - bankDenomMetadata, + fmt.Sprintf(`{"metadatas":%s,"pagination":{"next_key":null,"total":"2"}}`, bankDenomMetadata), }, { "test GRPC client metadata of a specific denom", denomMetadataUrl + "/uatom", - atomDenomMetadata, + fmt.Sprintf(`{"metadata":%s}`, atomDenomMetadata), }, { "test GRPC client metadata of a bogus denom", denomMetadataUrl + "/foobar", - `"details":[]`, + `{"code":5, "message":"client metadata for denom foobar", "details":[]}`, }, } - for _, tc := range dmTestCases { - t.Run(tc.name, func(t *testing.T) { - resp, err := testutil.GetRequest(tc.url) - require.NoError(t, err) - require.Contains(t, string(resp), tc.expOut) - }) - } + RunGRPCQueries(t, dmTestCases) // test bank balances endpoint balanceUrl := baseurl + "/cosmos/bank/v1beta1/balances/" allBalancesOutput := `{"balances":[` + specificDenomOutput + `,{"denom":"stake","amount":"10000000"}],"pagination":{"next_key":null,"total":"2"}}` - balanceTestCases := []struct { - name string - url string - expOut string - }{ + balanceTestCases := []GRPCTestCase{ { "test GRPC total account balance", balanceUrl + account1Addr, @@ -330,20 +312,14 @@ func TestBankGRPCQueries(t *testing.T) { { "test GRPC account balance of a specific denom", fmt.Sprintf("%s%s/by_denom?denom=%s", balanceUrl, account1Addr, newDenom), - specificDenomOutput, + fmt.Sprintf(`{"balance":%s}`, specificDenomOutput), }, { "test GRPC account balance of a bogus denom", fmt.Sprintf("%s%s/by_denom?denom=foobar", balanceUrl, account1Addr), - bogusDenomOutput, + fmt.Sprintf(`{"balance":%s}`, bogusDenomOutput), }, } - for _, tc := range balanceTestCases { - t.Run(tc.name, func(t *testing.T) { - resp, err := testutil.GetRequest(tc.url) - require.NoError(t, err) - require.Contains(t, string(resp), tc.expOut) - }) - } + RunGRPCQueries(t, balanceTestCases) } diff --git a/tests/systemtests/rest_cli.go b/tests/systemtests/rest_cli.go new file mode 100644 index 000000000000..c53533c0786f --- /dev/null +++ b/tests/systemtests/rest_cli.go @@ -0,0 +1,29 @@ +package systemtests + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/testutil" +) + +type GRPCTestCase struct { + name string + url string + expOut string +} + +// RunGRPCQueries runs given grpc testcases by making requests and +// checking response with expected output +func RunGRPCQueries(t *testing.T, testCases []GRPCTestCase) { + t.Helper() + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resp, err := testutil.GetRequest(tc.url) + require.NoError(t, err) + require.JSONEq(t, tc.expOut, string(resp)) + }) + } +} diff --git a/tests/systemtests/system.go b/tests/systemtests/system.go index 028645956d85..c4368c01558a 100644 --- a/tests/systemtests/system.go +++ b/tests/systemtests/system.go @@ -53,6 +53,7 @@ type SystemUnderTest struct { // since Tendermint consensus does not allow specifying it directly. blockTime time.Duration rpcAddr string + apiAddr string initialNodesCount int nodesCount int minGasPrice string @@ -86,6 +87,7 @@ func NewSystemUnderTest(execBinary string, verbose bool, nodesCount int, blockTi outputDir: "./testnet", blockTime: blockTime, rpcAddr: "tcp://localhost:26657", + apiAddr: fmt.Sprintf("http://localhost:%d", apiPortStart), initialNodesCount: nodesCount, outBuff: ring.New(100), errBuff: ring.New(100), @@ -638,6 +640,10 @@ func (s *SystemUnderTest) RPCClient(t *testing.T) RPCClient { return NewRPCClient(t, s.rpcAddr) } +func (s *SystemUnderTest) APIAddress() string { + return s.apiAddr +} + func (s *SystemUnderTest) AllPeers(t *testing.T) []string { t.Helper() result := make([]string, s.nodesCount) From 52d8b2eb43df267d80a6bbbd2b7067879466377d Mon Sep 17 00:00:00 2001 From: Marko Date: Tue, 1 Oct 2024 11:46:47 +0200 Subject: [PATCH 10/10] docs: amend docs for 52 changes (#21992) Co-authored-by: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> --- .../06-beginblock-endblock.md | 15 +++++-- docs/build/building-modules/06-keeper.md | 11 ++++- docs/build/building-modules/12-errors.md | 4 ++ docs/learn/advanced/05-encoding.md | 44 ++----------------- 4 files changed, 28 insertions(+), 46 deletions(-) diff --git a/docs/build/building-modules/06-beginblock-endblock.md b/docs/build/building-modules/06-beginblock-endblock.md index 51b72b7f056c..21c1a3303d3f 100644 --- a/docs/build/building-modules/06-beginblock-endblock.md +++ b/docs/build/building-modules/06-beginblock-endblock.md @@ -24,7 +24,7 @@ When needed, `BeginBlocker` and `EndBlocker` are implemented as part of the [`Ha The actual implementation of `BeginBlocker` and `EndBlocker` in `abci.go` are very similar to that of a [`Msg` service](./03-msg-services.md): -* They generally use the [`keeper`](./06-keeper.md) and [`ctx`](../../learn/advanced/02-context.md) to retrieve information about the latest state. +* They generally use the [`keeper`](./06-keeper.md) and [`ctx`](https://pkg.go.dev/context) to retrieve information about the latest state. * If needed, they use the `keeper` and `ctx` to trigger state-transitions. * If needed, they can emit [`events`](../../learn/advanced/08-events.md) via the `environments`'s `EventManager`. @@ -35,13 +35,20 @@ It is possible for developers to define the order of execution between the `Begi See an example implementation of `BeginBlocker` from the `distribution` module: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/distribution/abci.go#L14-L38 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/distribution/keeper/abci.go#L13-L40 ``` -and an example implementation of `EndBlocker` from the `staking` module: +and an example of `EndBlocker` from the `gov` module: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/abci.go#L22-L27 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/gov/keeper/abci.go#L22 ``` +and an example implementation of `EndBlocker` with validator updates from the `staking` module: + +```go reference +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/staking/keeper/abci.go#L12-L17 +``` + + diff --git a/docs/build/building-modules/06-keeper.md b/docs/build/building-modules/06-keeper.md index 1302a46d6324..0bd776ff9b9d 100644 --- a/docs/build/building-modules/06-keeper.md +++ b/docs/build/building-modules/06-keeper.md @@ -41,14 +41,14 @@ type Keeper struct { For example, here is the type definition of the `keeper` from the `staking` module: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/keeper.go#L23-L31 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/staking/keeper/keeper.go#L54-L115 ``` Let us go through the different parameters: * An expected `keeper` is a `keeper` external to a module that is required by the internal `keeper` of said module. External `keeper`s are listed in the internal `keeper`'s type definition as interfaces. These interfaces are themselves defined in an `expected_keepers.go` file in the root of the module's folder. In this context, interfaces are used to reduce the number of dependencies, as well as to facilitate the maintenance of the module itself. * `KVStoreService`s grant access to the store(s) of the [multistore](../../learn/advanced/04-store.md) managed by the module. They should always remain unexposed to external modules. -* `cdc` is the [codec](../../learn/advanced/05-encoding.md) used to marshall and unmarshall structs to/from `[]byte`. The `cdc` can be any of `codec.BinaryCodec`, `codec.JSONCodec` or `codec.Codec` based on your requirements. It can be either a proto or amino codec as long as they implement these interfaces. +* `cdc` is the [codec](../../learn/advanced/05-encoding.md) used to marshal and unmarshal structs to/from `[]byte`. The `cdc` can be any of `codec.BinaryCodec`, `codec.JSONCodec` or `codec.Codec` based on your requirements. It can be either a proto or amino codec as long as they implement these interfaces. * The authority listed is a module account or user account that has the right to change module level parameters. Previously this was handled by the param module, which has been deprecated. Of course, it is possible to define different types of internal `keeper`s for the same module (e.g. a read-only `keeper`). Each type of `keeper` comes with its own constructor function, which is called from the [application's constructor function](../../learn/beginner/00-app-anatomy.md). This is where `keeper`s are instantiated, and where developers make sure to pass correct instances of modules' `keeper`s to other modules that require them. @@ -60,3 +60,10 @@ Of course, it is possible to define different types of internal `keeper`s for th State management is recommended to be done via [Collections](../packages/collections) + +## State Management + +In the Cosmos SDK, it is crucial to be methodical and selective when managing state within a module, as improper state management can lead to inefficiency, security risks, and scalability issues. Not all data belongs in the on-chain state; it's important to store only essential blockchain data that needs to be verified by consensus. Storing unnecessary information, especially client-side data, can bloat the state and slow down performance. Instead, developers should focus on using an off-chain database to handle supplementary data, extending the API as needed. This approach minimizes on-chain complexity, optimizes resource usage, and keeps the blockchain state lean and efficient, ensuring scalability and smooth operations. + + +The Cosmos SDK leverages Protocol Buffers (protobuf) for efficient state management, providing a well-structured, binary encoding format that ensures compatibility and performance across different modules. The SDK’s recommended approach for managing state is through the [collections package](../pacakges/02-collections.md), which simplifies state handling by offering predefined data structures like maps and indexed sets, reducing the complexity of managing raw state data. While users can opt for custom encoding schemes if they need more flexibility or have specialized requirements, they should be aware that such custom implementations may not integrate seamlessly with indexers that decode state data on the fly. This could lead to challenges in data retrieval, querying, and interoperability, making protobuf a safer and more future-proof choice for most use cases. diff --git a/docs/build/building-modules/12-errors.md b/docs/build/building-modules/12-errors.md index b6935e62666e..20c7c512173d 100644 --- a/docs/build/building-modules/12-errors.md +++ b/docs/build/building-modules/12-errors.md @@ -14,6 +14,10 @@ common or general errors which can be further wrapped to provide additional spec There are two ways to return errors. You can register custom errors with a codespace that is meant to provide more information to clients and normal go errors. The Cosmos SDK uses a mixture of both. +:::Note +Errors v2 has been created as a zero dependency errors package. GRPC errors and tracing support is removed natively from the errors package. Users are required to wrap stack traces and add tracing information to their errors. +::: + :::Warning If errors are registered they are part of consensus and cannot be changed in a minor release ::: diff --git a/docs/learn/advanced/05-encoding.md b/docs/learn/advanced/05-encoding.md index 6df0dda2ec14..4a3af677d61d 100644 --- a/docs/learn/advanced/05-encoding.md +++ b/docs/learn/advanced/05-encoding.md @@ -47,7 +47,7 @@ via Protobuf. This means that modules may use Protobuf encoding, but the types m implement `ProtoMarshaler`. If modules wish to avoid implementing this interface for their types, this is autogenerated via [buf](https://buf.build/) -If modules use [Collections](../../build/packages/02-collections.md) or [ORM](../../build/packages/03-orm.md), encoding and decoding are handled, marshal and unmarshal should not be handled manually unless for specific cases identified by the developer. +Modules are recommended to use [collections](../../build/packages/02-collections.md) for handling encoding and decoding of state. Usage of collections handles marshal and unmarshal for you. By default protobuf is used but other encodings can be used if preferred. ### Gogoproto @@ -78,15 +78,15 @@ the consensus engine accepts only transactions in the form of raw bytes. * The `TxDecoder` object performs the decoding. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/tx_msg.go#L91-L95 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/types/tx_msg.go#L91-L95 ``` A standard implementation of both these objects can be found in the [`auth/tx` module](https://docs.cosmos.network/main/build/modules/auth#transactions): -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/tx/decoder.go +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/auth/tx/decoder.go ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/tx/encoder.go +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/x/auth/tx/encoder.go ``` See [ADR-020](../../architecture/adr-020-protobuf-transaction-encoding.md) for details of how a transaction is encoded. @@ -245,39 +245,3 @@ Protobuf types can be defined to encode: We encourage developers to follow industry guidelines: [Protocol Buffers style guide](https://developers.google.com/protocol-buffers/docs/style) and [Buf](https://buf.build/docs/style-guide), see more details in [ADR 023](../../architecture/adr-023-protobuf-naming.md) - -### How to update modules to protobuf encoding - -If modules do not contain any interfaces (e.g. `Account` or `Content`), then they -may simply migrate any existing types that -are encoded and persisted via their concrete Amino codec to Protobuf (see 1. for further guidelines) and accept a `Marshaler` as the codec which is implemented via the `ProtoCodec` -without any further customization. - -However, if a module type composes an interface, it must wrap it in the `sdk.Any` (from `/types` package) type. To do that, a module-level .proto file must use [`google.protobuf.Any`](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto) for respective message type interface types. - -For example, in the `x/evidence` module defines an `Evidence` interface, which is used by the `MsgSubmitEvidence`. The structure definition must use `sdk.Any` to wrap the evidence file. In the proto file we define it as follows: - -```protobuf -// proto/cosmos/evidence/v1beta1/tx.proto - -message MsgSubmitEvidence { - string submitter = 1; - google.protobuf.Any evidence = 2 [(cosmos_proto.accepts_interface) = "cosmos.evidence.v1beta1.Evidence"]; -} -``` - -The Cosmos SDK `codec.Codec` interface provides support methods `MarshalInterface` and `UnmarshalInterface` to easy encoding of state to `Any`. - -Module should register interfaces using `InterfaceRegistry` which provides a mechanism for registering interfaces: `RegisterInterface(protoName string, iface interface{}, impls ...proto.Message)` and implementations: `RegisterImplementations(iface interface{}, impls ...proto.Message)` that can be safely unpacked from Any, similarly to type registration with Amino: - -```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/codec/types/interface_registry.go#L28-L75 -``` - -In addition, an `UnpackInterfaces` phase should be introduced to deserialization to unpack interfaces before they're needed. Protobuf types that contain a protobuf `Any` either directly or via one of their members should implement the `UnpackInterfacesMessage` interface: - -```go -type UnpackInterfacesMessage interface { - UnpackInterfaces(InterfaceUnpacker) error -} -```