diff --git a/proto/cosmos/auth/v1beta1/auth.proto b/proto/cosmos/auth/v1beta1/auth.proto index 0caa12382907..71fc47eb9f88 100644 --- a/proto/cosmos/auth/v1beta1/auth.proto +++ b/proto/cosmos/auth/v1beta1/auth.proto @@ -46,4 +46,8 @@ message Params { [(gogoproto.customname) = "SigVerifyCostED25519", (gogoproto.moretags) = "yaml:\"sig_verify_cost_ed25519\""]; uint64 sig_verify_cost_secp256k1 = 5 [(gogoproto.customname) = "SigVerifyCostSecp256k1", (gogoproto.moretags) = "yaml:\"sig_verify_cost_secp256k1\""]; + uint64 pubkey_change_cost = 6 + [(gogoproto.customname) = "PubKeyChangeCost", (gogoproto.moretags) = "yaml:\"pubkey_change_cost\""]; + bool enable_change_pubkey = 7 + [(gogoproto.customname) = "EnableChangePubKey", (gogoproto.moretags) = "yaml:\"enable_change_pubkey\""]; } diff --git a/proto/cosmos/changepubkey/v1beta1/pubkey_history.proto b/proto/cosmos/changepubkey/v1beta1/pubkey_history.proto new file mode 100644 index 000000000000..7f5088540d58 --- /dev/null +++ b/proto/cosmos/changepubkey/v1beta1/pubkey_history.proto @@ -0,0 +1,80 @@ +syntax = "proto3"; +package cosmos.changepubkey.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types"; + +// Query defines the gRPC querier service for gov module +service Query { + // PubKeyHistory queries account pubkey history details based on address. + rpc PubKeyHistory(QueryPubKeyHistoryRequest) returns (QueryPubKeyHistoryResponse) { + option (google.api.http).get = "/cosmos/changepubkey/v1beta1/pubkey_history/{address}"; + } + + // PubKeyHistoricalEntry queries account pubkey historical entry based on address and time. + rpc PubKeyHistoricalEntry(QueryPubKeyHistoricalEntryRequest) returns (QueryPubKeyHistoricalEntryResponse) {} + + // LastPubKeyHistoricalEntry queries account's last pubkey historical entry based on address. + rpc LastPubKeyHistoricalEntry(QueryLastPubKeyHistoricalEntryRequest) returns (QueryLastPubKeyHistoricalEntryResponse) { + option (google.api.http).get = "/cosmos/changepubkey/v1beta1/last_pubkey_historical_entry/{address}"; + } + + // CurrentPubKeyEntry queries account's current pubkey entry based on address. + rpc CurrentPubKeyEntry(QueryCurrentPubKeyEntryRequest) returns (QueryCurrentPubKeyEntryResponse) { + option (google.api.http).get = "/cosmos/changepubkey/v1beta1/current_pubkey_entry/{address}"; + } +} + +message PubKeyHistory { + bytes pub_key = 1 + [(gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\""]; + google.protobuf.Timestamp start_time = 2 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"start_time\""]; + google.protobuf.Timestamp end_time = 3 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"end_time\""]; +} + +// QueryPubKeyHistoryRequest is the request type for the Query/PubKeyHistory RPC method. +message QueryPubKeyHistoryRequest { + string address = 1; +} + +// QueryPubKeyHistoryResponse is the response type for the Query/PubKeyHistory RPC method. +message QueryPubKeyHistoryResponse { + repeated PubKeyHistory history = 1 [(gogoproto.nullable) = false]; +} + +// QueryPubKeyHistoricalEntryRequest is the request type for the Query/PubKeyHistoricalEntry RPC method. +message QueryPubKeyHistoricalEntryRequest { + string address = 1; + google.protobuf.Timestamp time = 2 + [(gogoproto.stdtime) = true, (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"time\""]; +} + +// QueryPubKeyHistoricalEntryResponse is the response type for the Query/PubKeyHistoricalEntry RPC method. +message QueryPubKeyHistoricalEntryResponse { + PubKeyHistory entry = 1 [(gogoproto.nullable) = false]; +} + +// QueryLastPubKeyHistoricalEntryRequest is the request type for the Query/LastPubKeyHistoricalEntry RPC method. +message QueryLastPubKeyHistoricalEntryRequest { + string address = 1; +} + +// QueryLastPubKeyHistoricalEntryResponse is the response type for the Query/LastPubKeyHistoricalEntry RPC method. +message QueryLastPubKeyHistoricalEntryResponse { + PubKeyHistory entry = 1 [(gogoproto.nullable) = false]; +} + +// QueryCurrentPubKeyEntryRequest is the request type for the Query/CurrentPubKeyEntry RPC method. +message QueryCurrentPubKeyEntryRequest { + string address = 1; +} + +// QueryCurrentPubKeyEntryResponse is the response type for the Query/LastPubKeyHistoricalEntry RPC method. +message QueryCurrentPubKeyEntryResponse { + PubKeyHistory entry = 1 [(gogoproto.nullable) = false]; +} diff --git a/proto/cosmos/changepubkey/v1beta1/tx.proto b/proto/cosmos/changepubkey/v1beta1/tx.proto new file mode 100644 index 000000000000..b5c904b3c1d5 --- /dev/null +++ b/proto/cosmos/changepubkey/v1beta1/tx.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package cosmos.changepubkey.v1beta1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types"; + +// Msg defines the changepubkey Msg service. +service Msg { + // ChangePubKey defines a method for changing a pubkey of an account + rpc ChangePubKey(MsgChangePubKey) returns (MsgChangePubKeyResponse); +} + +// MsgChangePubKey defines a message that enables changing a pubkey +// of an account. +message MsgChangePubKey { + bytes address = 1 [ + (gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress" + ]; + bytes pub_key = 2 [ + (gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\"" + ]; +} + +// MsgChangePubKeyResponse defines the Msg/ChangePubKey response type. +message MsgChangePubKeyResponse { } \ No newline at end of file diff --git a/simapp/_localsetup.sh b/simapp/_localsetup.sh new file mode 100644 index 000000000000..d4b56b3acb63 --- /dev/null +++ b/simapp/_localsetup.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +rm -rf $HOME/.simd/ + +cd $HOME + +simd init --chain-id=testing testing --home=$HOME/.simd +simd keys add validator --keyring-backend=test --home=$HOME/.simd +simd add-genesis-account $(simd keys show validator -a --keyring-backend=test --home=$HOME/.simd) 1000000000validatortoken,1000000000stake --home=$HOME/.simd +simd gentx validator --keyring-backend=test --home=$HOME/.simd --chain-id testing +simd collect-gentxs --home=$HOME/.simd + +simd start --home=$HOME/.simd diff --git a/simapp/app.go b/simapp/app.go index a8c9e584be27..276186aa8a63 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -31,6 +31,9 @@ import ( "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/ante" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey" + changepubkeykeeper "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/keeper" + changepubkeytypes "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" @@ -101,6 +104,7 @@ var ( // and genesis verification. ModuleBasics = module.NewBasicManager( auth.AppModuleBasic{}, + changepubkey.AppModuleBasic{}, genutil.AppModuleBasic{}, bank.AppModuleBasic{}, capability.AppModuleBasic{}, @@ -159,20 +163,21 @@ type SimApp struct { memKeys map[string]*sdk.MemoryStoreKey // keepers - AccountKeeper authkeeper.AccountKeeper - BankKeeper bankkeeper.Keeper - CapabilityKeeper *capabilitykeeper.Keeper - StakingKeeper stakingkeeper.Keeper - SlashingKeeper slashingkeeper.Keeper - MintKeeper mintkeeper.Keeper - DistrKeeper distrkeeper.Keeper - GovKeeper govkeeper.Keeper - CrisisKeeper crisiskeeper.Keeper - UpgradeKeeper upgradekeeper.Keeper - ParamsKeeper paramskeeper.Keeper - IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly - EvidenceKeeper evidencekeeper.Keeper - TransferKeeper ibctransferkeeper.Keeper + AccountKeeper authkeeper.AccountKeeper + AccountHistoryKeeper changepubkeykeeper.Keeper + BankKeeper bankkeeper.Keeper + CapabilityKeeper *capabilitykeeper.Keeper + StakingKeeper stakingkeeper.Keeper + SlashingKeeper slashingkeeper.Keeper + MintKeeper mintkeeper.Keeper + DistrKeeper distrkeeper.Keeper + GovKeeper govkeeper.Keeper + CrisisKeeper crisiskeeper.Keeper + UpgradeKeeper upgradekeeper.Keeper + ParamsKeeper paramskeeper.Keeper + IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + EvidenceKeeper evidencekeeper.Keeper + TransferKeeper ibctransferkeeper.Keeper // make scoped keepers public for test purposes ScopedIBCKeeper capabilitykeeper.ScopedKeeper @@ -217,6 +222,7 @@ func NewSimApp( minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, + changepubkeytypes.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) @@ -249,6 +255,9 @@ func NewSimApp( app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, maccPerms, ) + app.AccountHistoryKeeper = changepubkeykeeper.NewKeeper( + appCodec, keys[changepubkeytypes.StoreKey], app.AccountKeeper, + ) app.BankKeeper = bankkeeper.NewBaseKeeper( appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.BlockedAddrs(), ) @@ -334,6 +343,7 @@ func NewSimApp( ), auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts), vesting.NewAppModule(app.AccountKeeper, app.BankKeeper), + changepubkey.NewAppModule(app.AccountKeeper, app.AccountHistoryKeeper), bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper), capability.NewAppModule(appCodec, *app.CapabilityKeeper), crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants), @@ -365,7 +375,7 @@ func NewSimApp( // so that other modules that want to create or claim capabilities afterwards in InitChain // can do so safely. app.mm.SetOrderInitGenesis( - capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, + capabilitytypes.ModuleName, authtypes.ModuleName, changepubkeytypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName, ibchost.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, ibctransfertypes.ModuleName, ) @@ -601,6 +611,7 @@ func initParamsKeeper(appCodec codec.BinaryMarshaler, legacyAmino *codec.LegacyA paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) paramsKeeper.Subspace(authtypes.ModuleName) + paramsKeeper.Subspace(changepubkeytypes.ModuleName) paramsKeeper.Subspace(banktypes.ModuleName) paramsKeeper.Subspace(stakingtypes.ModuleName) paramsKeeper.Subspace(minttypes.ModuleName) diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index 6fa3325c792b..5107fa7ab883 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -26,6 +26,7 @@ import ( "github.com/cosmos/cosmos-sdk/snapshots" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" + changepubkeycmd "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/client/cli" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -159,6 +160,7 @@ func txCommand() *cobra.Command { authcmd.GetDecodeCommand(), flags.LineBreak, vestingcli.GetTxCmd(), + changepubkeycmd.GetTxCmd(), ) simapp.ModuleBasics.AddTxCommands(cmd) diff --git a/std/codec.go b/std/codec.go index 7310d75a25fd..f8a9d62a8166 100644 --- a/std/codec.go +++ b/std/codec.go @@ -6,6 +6,8 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" txtypes "github.com/cosmos/cosmos-sdk/types/tx" + changepubkey "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" + vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" ) // RegisterLegacyAminoCodec registers types with the Amino codec. @@ -19,4 +21,6 @@ func RegisterInterfaces(interfaceRegistry types.InterfaceRegistry) { sdk.RegisterInterfaces(interfaceRegistry) txtypes.RegisterInterfaces(interfaceRegistry) cryptocodec.RegisterInterfaces(interfaceRegistry) + vesting.RegisterInterfaces(interfaceRegistry) + changepubkey.RegisterInterfaces(interfaceRegistry) } diff --git a/testutil/testdata/tx.go b/testutil/testdata/tx.go index 09e1e365f1ca..c21b929be545 100644 --- a/testutil/testdata/tx.go +++ b/testutil/testdata/tx.go @@ -24,7 +24,7 @@ func NewTestFeeAmount() sdk.Coins { // NewTestGasLimit is a test fee gas limit. func NewTestGasLimit() uint64 { - return 100000 + return 150000 } // NewTestMsg creates a message for testing with the given signers. diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index 0d9ef82f44be..4713a4dcce34 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -82,6 +82,8 @@ func (suite *AnteTestSuite) TestAnteHandlerSigErrors() { priv0, _, addr0 := testdata.KeyTestPubAddr() priv1, _, addr1 := testdata.KeyTestPubAddr() priv2, _, addr2 := testdata.KeyTestPubAddr() + priv3, _, addr3 := testdata.KeyTestPubAddr() + _, _, addr4 := testdata.KeyTestPubAddr() msgs := []sdk.Msg{ testdata.NewTestMsg(addr0, addr1), testdata.NewTestMsg(addr0, addr2), @@ -144,6 +146,41 @@ func (suite *AnteTestSuite) TestAnteHandlerSigErrors() { false, sdkerrors.ErrUnknownAddress, }, + { + "provide wrong pubkey for account with changed pubkey", + func() { + acc3 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr3) + acc3.SetPubKey(priv2.PubKey()) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc3) + err := suite.app.BankKeeper.SetBalances(suite.ctx, addr3, feeAmount) + suite.Require().NoError(err) + msg := testdata.NewTestMsg(addr3) + msgs = []sdk.Msg{msg} + // we should provide priv2 since we changed pubkey of acc3 to priv2.PubKey() + // but since it provide priv3, it should fail for InvalidPubKey + privs, accNums, accSeqs = []crypto.PrivKey{priv3}, []uint64{acc3.GetAccountNumber()}, []uint64{0} + }, + false, + false, + sdkerrors.ErrInvalidPubKey, + }, + { + "provide correct pubkey for account with changed pubkey", + func() { + acc4 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr4) + acc4.SetPubKey(priv2.PubKey()) + suite.app.AccountKeeper.SetAccount(suite.ctx, acc4) + err := suite.app.BankKeeper.SetBalances(suite.ctx, addr4, feeAmount) + suite.Require().NoError(err) + msg := testdata.NewTestMsg(addr4) + msgs = []sdk.Msg{msg} + // we provide priv2 since we changed pubkey of acc4 to priv2.PubKey() + privs, accNums, accSeqs = []crypto.PrivKey{priv2}, []uint64{acc4.GetAccountNumber()}, []uint64{0} + }, + false, + true, + nil, + }, } for _, tc := range testCases { @@ -1091,9 +1128,9 @@ func (suite *AnteTestSuite) TestAnteHandlerReCheck() { name string params types.Params }{ - {"memo size check", types.NewParams(1, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1)}, - {"txsize check", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, 10000000, types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1)}, - {"sig verify cost check", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, types.DefaultSigVerifyCostED25519, 100000000)}, + {"memo size check", types.NewParams(1, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1, types.DefaultPubKeyChangeCost, types.DefaultEnableChangePubKey)}, + {"txsize check", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, 10000000, types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1, types.DefaultPubKeyChangeCost, types.DefaultEnableChangePubKey)}, + {"sig verify cost check", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, types.DefaultSigVerifyCostED25519, 100000000, types.DefaultPubKeyChangeCost, types.DefaultEnableChangePubKey)}, } for _, tc := range testCases { // set testcase parameters diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index 80ea9317e1c7..72386f9ba784 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -70,20 +70,28 @@ func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b } pk = simSecp256k1Pubkey } - // Only make check if simulate=false - if !simulate && !bytes.Equal(pk.Address(), signers[i]) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, - "pubKey does not match signer address %s with signer index: %d", signers[i], i) - } - acc, err := GetSignerAcc(ctx, spkd.ak, signers[i]) if err != nil { return ctx, err } // account already has pubkey set,no need to reset if acc.GetPubKey() != nil { + // Check to make sure the pubkeys match + // Only make check if simulate=false + if !simulate && !bytes.Equal(pk.Address(), acc.GetPubKey().Address()) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, + "pubKey does not match existing one assigned to address %s with signer index: %d", signers[i], i) + } continue } + + // If pubkey is not set on an account, make sure that pubkey from address hashes to account address + // Only make check if simulate=false and if pubkey is not available + if !simulate && !bytes.Equal(pk.Address(), signers[i]) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, + "pubKey does not match signer address %s with signer index: %d", signers[i], i) + } + err = acc.SetPubKey(pk) if err != nil { return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidPubKey, err.Error()) diff --git a/x/auth/changepubkey/client/cli/cli_test.go b/x/auth/changepubkey/client/cli/cli_test.go new file mode 100644 index 000000000000..6d275a0befc8 --- /dev/null +++ b/x/auth/changepubkey/client/cli/cli_test.go @@ -0,0 +1,113 @@ +// +build norace + +package cli_test + +import ( + "fmt" + "testing" + + "github.com/gogo/protobuf/proto" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/client/flags" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + "github.com/cosmos/cosmos-sdk/testutil/network" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/client/cli" +) + +type IntegrationTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network +} + +func (s *IntegrationTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + cfg := network.DefaultConfig() + cfg.NumValidators = 1 + + s.cfg = cfg + s.network = network.New(s.T(), cfg) + + _, err := s.network.WaitForHeight(1) + s.Require().NoError(err) +} + +func (s *IntegrationTestSuite) TearDownSuite() { + s.T().Log("tearing down integration test suite") + s.network.Cleanup() +} + +func (s *IntegrationTestSuite) TestNewMsgChangePubKeyCmd() { + val := s.network.Validators[0] + + testCases := map[string]struct { + args []string + expectErr bool + respType proto.Message + expectedCode uint32 + }{ + // simd tx changepubkey change-pubkey cosmospub1addwnpepqdszcr95mrqqs8lw099aa9h8h906zmet22pmwe9vquzcgvnm93eqygufdlv --from validator --keyring-backend=test --chain-id=testing --home=$HOME/.simd + "try changing pubkey": { + args: []string{ + "cosmospub1addwnpepqdszcr95mrqqs8lw099aa9h8h906zmet22pmwe9vquzcgvnm93eqygufdlv", + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + expectErr: false, + respType: &sdk.TxResponse{}, + expectedCode: 0, + }, + "wrong pubkey set": { + args: []string{ + "cosmospub1adXXXXX", + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + expectErr: true, + respType: &sdk.TxResponse{}, + expectedCode: 0, + }, + "no from flag set": { + args: []string{ + "cosmospub1addwnpepqdszcr95mrqqs8lw099aa9h8h906zmet22pmwe9vquzcgvnm93eqygufdlv", + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + expectErr: true, + respType: &sdk.TxResponse{}, + expectedCode: 0, + }, + } + + for name, tc := range testCases { + tc := tc + + s.Run(name, func() { + clientCtx := val.ClientCtx + + bw, err := clitestutil.ExecTestCLICmd(clientCtx, cli.NewMsgChangePubKeyCmd(), tc.args) + if tc.expectErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONMarshaler.UnmarshalJSON(bw.Bytes(), tc.respType), bw.String()) + + txResp := tc.respType.(*sdk.TxResponse) + s.Require().Equal(tc.expectedCode, txResp.Code) + } + }) + } +} + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} diff --git a/x/auth/changepubkey/client/cli/query.go b/x/auth/changepubkey/client/cli/query.go new file mode 100644 index 000000000000..ea072741b637 --- /dev/null +++ b/x/auth/changepubkey/client/cli/query.go @@ -0,0 +1,179 @@ +package cli + +import ( + "context" + "strconv" + "time" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" +) + +// GetQueryCmd returns the transaction commands for this module +func GetQueryCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Querying commands for the auth module", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + GetPubKeyHistoryCmd(), + GetPubKeyHistoricalEntryCmd(), + GetLastPubKeyHistoricalEntryCmd(), + GetCurrentPubKeyEntryCmd(), + ) + + return cmd +} + +// GetPubKeyHistoryCmd returns a query account pubkey history +func GetPubKeyHistoryCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "pubkey_history [address]", + Short: "Query for pubkey_history by address", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } + + key, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.PubKeyHistory(context.Background(), &types.QueryPubKeyHistoryRequest{Address: key.String()}) + if err != nil { + return err + } + + return clientCtx.PrintOutput(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetPubKeyHistoricalEntryCmd returns a query account pubkey history +func GetPubKeyHistoricalEntryCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "historical_entry [address] [time]", + Short: "Query for pubkey historical entry by address and time", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } + + key, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + timestamp, err := strconv.ParseInt(args[1], 10, 64) + if err != nil { + return err + } + time := time.Unix(timestamp, 0) + + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.PubKeyHistoricalEntry(context.Background(), &types.QueryPubKeyHistoricalEntryRequest{ + Address: key.String(), + Time: time, + }) + if err != nil { + return err + } + + return clientCtx.PrintOutput(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetLastPubKeyHistoricalEntryCmd returns a query account pubkey history +func GetLastPubKeyHistoricalEntryCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "last_pubkey_historical_entry [address]", + Short: "Query for last pubkey historical entry by address", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } + + key, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.LastPubKeyHistoricalEntry(context.Background(), &types.QueryLastPubKeyHistoricalEntryRequest{ + Address: key.String(), + }) + if err != nil { + return err + } + + return clientCtx.PrintOutput(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCurrentPubKeyEntryCmd returns a query account pubkey history +func GetCurrentPubKeyEntryCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "current_pubkey_entry [address]", + Short: "Query for current pubkey entry by address", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + clientCtx, err := client.ReadQueryCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } + + key, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.CurrentPubKeyEntry(context.Background(), &types.QueryCurrentPubKeyEntryRequest{ + Address: key.String(), + }) + if err != nil { + return err + } + + return clientCtx.PrintOutput(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/auth/changepubkey/client/cli/tx.go b/x/auth/changepubkey/client/cli/tx.go new file mode 100644 index 000000000000..97fa0f4666b2 --- /dev/null +++ b/x/auth/changepubkey/client/cli/tx.go @@ -0,0 +1,70 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" +) + +// Transaction command flags +const ( + FlagDelayed = "delayed" +) + +// GetTxCmd returns changepubkey module's transaction commands. +func GetTxCmd() *cobra.Command { + txCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "changepubkey transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + txCmd.AddCommand( + NewMsgChangePubKeyCmd(), + ) + + return txCmd +} + +// NewMsgChangePubKeyCmd returns a CLI command handler for creating a +// MsgChangePubKey transaction. +func NewMsgChangePubKeyCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "change-pubkey [pubkey]", + Short: "Change PubKey of an account.", + Long: `This msg will update the public key associated with an account + to a new public key, while keeping the same address. + This can be used for purposes such as passing ownership of an account + to a new key for security reasons or upgrading multisig signers.`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) + if err != nil { + return err + } + + pubKey, err := sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, args[0]) + if err != nil { + return err + } + + msg := types.NewMsgChangePubKey(clientCtx.GetFromAddress(), pubKey) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/auth/changepubkey/handler.go b/x/auth/changepubkey/handler.go new file mode 100644 index 000000000000..3c346917d3ff --- /dev/null +++ b/x/auth/changepubkey/handler.go @@ -0,0 +1,27 @@ +package changepubkey + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + changepubkeykeeper "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/keeper" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" +) + +// NewHandler returns a handler for x/auth message types. +func NewHandler(ak authkeeper.AccountKeeper, hk changepubkeykeeper.Keeper) sdk.Handler { + msgServer := changepubkeykeeper.NewMsgServerImpl(ak, hk) + + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + ctx = ctx.WithEventManager(sdk.NewEventManager()) + + switch msg := msg.(type) { + case *types.MsgChangePubKey: + res, err := msgServer.ChangePubKey(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) + } + } +} diff --git a/x/auth/changepubkey/handler_test.go b/x/auth/changepubkey/handler_test.go new file mode 100644 index 000000000000..c3961be12d38 --- /dev/null +++ b/x/auth/changepubkey/handler_test.go @@ -0,0 +1,94 @@ +package changepubkey_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/stretchr/testify/suite" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + changepubkey "github.com/cosmos/cosmos-sdk/x/auth/changepubkey" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" +) + +type HandlerTestSuite struct { + suite.Suite + + handler sdk.Handler + app *simapp.SimApp +} + +func (suite *HandlerTestSuite) SetupTest() { + checkTx := false + app := simapp.Setup(checkTx) + + suite.handler = changepubkey.NewHandler(app.AccountKeeper, app.AccountHistoryKeeper) + suite.app = app +} + +func (suite *HandlerTestSuite) TestMsgChangePubKey() { + ctx := suite.app.BaseApp.NewContext(false, tmproto.Header{Height: suite.app.LastBlockHeight() + 1}) + + addr1 := sdk.AccAddress([]byte("any----------address")) + acc1 := suite.app.AccountKeeper.NewAccountWithAddress(ctx, addr1) + suite.app.AccountKeeper.SetAccount(ctx, acc1) + suite.Require().NoError(suite.app.BankKeeper.SetBalances(ctx, addr1, sdk.NewCoins(sdk.NewInt64Coin("stake", 1000)))) + + addr2 := sdk.AccAddress([]byte("some---------address")) + acc2 := suite.app.AccountKeeper.NewAccountWithAddress(ctx, addr2) + suite.Require().NotNil(acc2) + suite.Require().Equal(addr2, acc2.GetAddress()) + + suite.app.AccountKeeper.SetAccount(ctx, acc2) + suite.Require().NotNil(suite.app.AccountKeeper.GetAccount(ctx, addr2)) + suite.Require().NoError(suite.app.BankKeeper.SetBalances(ctx, addr2, sdk.NewCoins(sdk.NewInt64Coin("stake", 10000)))) + + privKey := secp256k1.GenPrivKeyFromSecret([]byte("mySecret")) + pubKey := privKey.PubKey() + + testCases := []struct { + name string + msg *types.MsgChangePubKey + enableChangePubKey bool + expectErr bool + }{ + { + name: "try changing pubkey", + msg: types.NewMsgChangePubKey(addr2, pubKey), + expectErr: false, + enableChangePubKey: true, + }, + { + name: "try changing pubkey", + msg: types.NewMsgChangePubKey(addr2, pubKey), + expectErr: true, + enableChangePubKey: false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(tc.name, func() { + authParams := suite.app.AccountKeeper.GetParams(ctx) + authParams.EnableChangePubKey = tc.enableChangePubKey + suite.app.AccountKeeper.SetParams(ctx, authParams) + res, err := suite.handler(ctx, tc.msg) + if tc.expectErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().NotNil(res) + + accI := suite.app.AccountKeeper.GetAccount(ctx, tc.msg.Address) + suite.Require().NotNil(accI) + } + }) + } +} + +func TestHandlerTestSuite(t *testing.T) { + suite.Run(t, new(HandlerTestSuite)) +} diff --git a/x/auth/changepubkey/keeper/grpc_query.go b/x/auth/changepubkey/keeper/grpc_query.go new file mode 100644 index 000000000000..7b7c631d1c28 --- /dev/null +++ b/x/auth/changepubkey/keeper/grpc_query.go @@ -0,0 +1,96 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +var _ types.QueryServer = Keeper{} + +// PubKeyHistory queries account pubkey history details based on address. +func (k Keeper) PubKeyHistory(goCtx context.Context, req *types.QueryPubKeyHistoryRequest) (*types.QueryPubKeyHistoryResponse, error) { + if req == nil { + return nil, status.Errorf(codes.InvalidArgument, "empty request") + } + + if req.Address == "" { + return nil, status.Error(codes.InvalidArgument, "Address cannot be empty") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + addr, err := sdk.AccAddressFromBech32(req.Address) + if err != nil { + return nil, err + } + + history, err := k.GetPubKeyHistory(ctx, addr) + return &types.QueryPubKeyHistoryResponse{History: history}, err +} + +// PubKeyHistoricalEntry queries account pubkey historical entry based on address and time. +func (k Keeper) PubKeyHistoricalEntry(goCtx context.Context, req *types.QueryPubKeyHistoricalEntryRequest) (*types.QueryPubKeyHistoricalEntryResponse, error) { + if req == nil { + return nil, status.Errorf(codes.InvalidArgument, "empty request") + } + + if req.Address == "" { + return nil, status.Error(codes.InvalidArgument, "Address cannot be empty") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + addr, err := sdk.AccAddressFromBech32(req.Address) + if err != nil { + return nil, err + } + + entry := k.GetPubKeyHistoricalEntry(ctx, addr, req.Time) + return &types.QueryPubKeyHistoricalEntryResponse{Entry: entry}, nil +} + +// LastPubKeyHistoricalEntry queries account's last pubkey historical entry based on address. +func (k Keeper) LastPubKeyHistoricalEntry(goCtx context.Context, req *types.QueryLastPubKeyHistoricalEntryRequest) (*types.QueryLastPubKeyHistoricalEntryResponse, error) { + if req == nil { + return nil, status.Errorf(codes.InvalidArgument, "empty request") + } + + if req.Address == "" { + return nil, status.Error(codes.InvalidArgument, "Address cannot be empty") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + addr, err := sdk.AccAddressFromBech32(req.Address) + if err != nil { + return nil, err + } + + entry := k.GetLastPubKeyHistoricalEntry(ctx, addr) + return &types.QueryLastPubKeyHistoricalEntryResponse{Entry: entry}, nil +} + +// CurrentPubKeyEntry queries account's current pubkey entry based on address. +func (k Keeper) CurrentPubKeyEntry(goCtx context.Context, req *types.QueryCurrentPubKeyEntryRequest) (*types.QueryCurrentPubKeyEntryResponse, error) { + if req == nil { + return nil, status.Errorf(codes.InvalidArgument, "empty request") + } + + if req.Address == "" { + return nil, status.Error(codes.InvalidArgument, "Address cannot be empty") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + addr, err := sdk.AccAddressFromBech32(req.Address) + if err != nil { + return nil, err + } + + entry := k.GetCurrentPubKeyEntry(ctx, addr) + return &types.QueryCurrentPubKeyEntryResponse{Entry: entry}, nil +} diff --git a/x/auth/changepubkey/keeper/grpc_query_test.go b/x/auth/changepubkey/keeper/grpc_query_test.go new file mode 100644 index 000000000000..474d97ca7459 --- /dev/null +++ b/x/auth/changepubkey/keeper/grpc_query_test.go @@ -0,0 +1,369 @@ +package keeper_test + +import ( + "fmt" + "time" + + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/keeper" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" +) + +func (suite *KeeperTestSuite) TestGRPCQueryAccountPubKeyHistory() { + var ( + req *types.QueryPubKeyHistoryRequest + ) + _, pub1, addr := testdata.KeyTestPubAddr() + _, pub2, _ := testdata.KeyTestPubAddr() + + testCases := []struct { + msg string + malleate func() + expPass bool + posttests func(res *types.QueryPubKeyHistoryResponse) + }{ + { + "empty request", + func() { + req = &types.QueryPubKeyHistoryRequest{} + }, + false, + func(res *types.QueryPubKeyHistoryResponse) {}, + }, + { + "invalid request", + func() { + req = &types.QueryPubKeyHistoryRequest{Address: ""} + }, + false, + func(res *types.QueryPubKeyHistoryResponse) {}, + }, + { + "account not found", + func() { + req = &types.QueryPubKeyHistoryRequest{Address: addr.String()} + }, + false, + func(res *types.QueryPubKeyHistoryResponse) {}, + }, + { + "success", + func() { + suite.app.AccountKeeper.SetAccount(suite.ctx, + suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)) + req = &types.QueryPubKeyHistoryRequest{Address: addr.String()} + }, + true, + func(res *types.QueryPubKeyHistoryResponse) { + suite.Require().Equal(len(res.History), 1) + }, + }, + { + "success with more history", + func() { + suite.app.AccountKeeper.SetAccount(suite.ctx, suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)) + + msgServer := keeper.NewMsgServerImpl(suite.app.AccountKeeper, suite.app.AccountHistoryKeeper) + _, err := msgServer.ChangePubKey(sdk.WrapSDKContext(suite.ctx), types.NewMsgChangePubKey(addr, pub1)) + suite.Require().NoError(err) + suite.ctx = suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(time.Minute)) + + _, err = msgServer.ChangePubKey(sdk.WrapSDKContext(suite.ctx), types.NewMsgChangePubKey(addr, pub2)) + suite.Require().NoError(err) + suite.ctx = suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(time.Minute)) + + req = &types.QueryPubKeyHistoryRequest{Address: addr.String()} + }, + true, + func(res *types.QueryPubKeyHistoryResponse) { + suite.Require().Equal(len(res.History), 3) + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.History[0].PubKey), nil) + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.History[1].PubKey), pub1) + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.History[2].PubKey), pub2) + }, + }, + } + + for _, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + ctx := sdk.WrapSDKContext(suite.ctx) + + res, err := suite.queryClient.PubKeyHistory(ctx, req) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + } else { + suite.Require().Error(err) + suite.Require().Nil(res) + } + + tc.posttests(res) + }) + } +} + +func (suite *KeeperTestSuite) TestGRPCQueryAccountPubKeyHistoricalEntry() { + var ( + req *types.QueryPubKeyHistoricalEntryRequest + ) + _, pub1, addr := testdata.KeyTestPubAddr() + _, pub2, _ := testdata.KeyTestPubAddr() + + testCases := []struct { + msg string + malleate func() + expPass bool + posttests func(res *types.QueryPubKeyHistoricalEntryResponse) + }{ + { + "empty request", + func() { + req = &types.QueryPubKeyHistoricalEntryRequest{} + }, + false, + func(res *types.QueryPubKeyHistoricalEntryResponse) {}, + }, + { + "invalid request", + func() { + req = &types.QueryPubKeyHistoricalEntryRequest{Address: ""} + }, + false, + func(res *types.QueryPubKeyHistoricalEntryResponse) {}, + }, + { + "account not found", + func() { + req = &types.QueryPubKeyHistoricalEntryRequest{Address: addr.String()} + }, + true, + func(res *types.QueryPubKeyHistoricalEntryResponse) { + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.Entry.PubKey), nil) + }, + }, + { + "account found empty but pubkey", + func() { + suite.app.AccountKeeper.SetAccount(suite.ctx, + suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)) + req = &types.QueryPubKeyHistoricalEntryRequest{Address: addr.String()} + }, + true, + func(res *types.QueryPubKeyHistoricalEntryResponse) { + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.Entry.PubKey), nil) + }, + }, + { + "query with more history", + func() { + suite.app.AccountKeeper.SetAccount(suite.ctx, suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)) + suite.ChangeAccountPubKeys(addr, pub1, pub2) + req = &types.QueryPubKeyHistoricalEntryRequest{Address: addr.String(), Time: suite.ctx.BlockTime().Truncate(100 * time.Minute)} + }, + true, + func(res *types.QueryPubKeyHistoricalEntryResponse) { + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.Entry.PubKey), nil) + }, + }, + } + + for _, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + ctx := sdk.WrapSDKContext(suite.ctx) + + res, err := suite.queryClient.PubKeyHistoricalEntry(ctx, req) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + } else { + suite.Require().Error(err) + suite.Require().Nil(res) + } + + tc.posttests(res) + }) + } +} + +func (suite *KeeperTestSuite) TestGRPCQueryAccountLastPubKeyHistoricalEntry() { + var ( + req *types.QueryLastPubKeyHistoricalEntryRequest + ) + _, pub1, addr := testdata.KeyTestPubAddr() + _, pub2, _ := testdata.KeyTestPubAddr() + + testCases := []struct { + msg string + malleate func() + expPass bool + posttests func(res *types.QueryLastPubKeyHistoricalEntryResponse) + }{ + { + "empty request", + func() { + req = &types.QueryLastPubKeyHistoricalEntryRequest{} + }, + false, + func(res *types.QueryLastPubKeyHistoricalEntryResponse) {}, + }, + { + "invalid request", + func() { + req = &types.QueryLastPubKeyHistoricalEntryRequest{Address: ""} + }, + false, + func(res *types.QueryLastPubKeyHistoricalEntryResponse) {}, + }, + { + "account not found", + func() { + req = &types.QueryLastPubKeyHistoricalEntryRequest{Address: addr.String()} + }, + true, + func(res *types.QueryLastPubKeyHistoricalEntryResponse) { + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.Entry.PubKey), nil) + }, + }, + { + "account found empty but pubkey", + func() { + suite.app.AccountKeeper.SetAccount(suite.ctx, + suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)) + req = &types.QueryLastPubKeyHistoricalEntryRequest{Address: addr.String()} + }, + true, + func(res *types.QueryLastPubKeyHistoricalEntryResponse) { + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.Entry.PubKey), nil) + }, + }, + { + "query with more history", + func() { + suite.app.AccountKeeper.SetAccount(suite.ctx, suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)) + suite.ChangeAccountPubKeys(addr, pub1, pub2) + req = &types.QueryLastPubKeyHistoricalEntryRequest{Address: addr.String()} + }, + true, + func(res *types.QueryLastPubKeyHistoricalEntryResponse) { + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.Entry.PubKey), pub1) + }, + }, + } + + for _, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + ctx := sdk.WrapSDKContext(suite.ctx) + + res, err := suite.queryClient.LastPubKeyHistoricalEntry(ctx, req) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + } else { + suite.Require().Error(err) + suite.Require().Nil(res) + } + + tc.posttests(res) + }) + } +} + +func (suite *KeeperTestSuite) TestGRPCQueryAccountCurrentPubKeyHistoricalEntry() { + var ( + req *types.QueryCurrentPubKeyEntryRequest + ) + _, pub1, addr := testdata.KeyTestPubAddr() + _, pub2, _ := testdata.KeyTestPubAddr() + + testCases := []struct { + msg string + malleate func() + expPass bool + posttests func(res *types.QueryCurrentPubKeyEntryResponse) + }{ + { + "empty request", + func() { + req = &types.QueryCurrentPubKeyEntryRequest{} + }, + false, + func(res *types.QueryCurrentPubKeyEntryResponse) {}, + }, + { + "invalid request", + func() { + req = &types.QueryCurrentPubKeyEntryRequest{Address: ""} + }, + false, + func(res *types.QueryCurrentPubKeyEntryResponse) {}, + }, + { + "account not found", + func() { + req = &types.QueryCurrentPubKeyEntryRequest{Address: addr.String()} + }, + true, + func(res *types.QueryCurrentPubKeyEntryResponse) { + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.Entry.PubKey), nil) + }, + }, + { + "account found empty but pubkey", + func() { + suite.app.AccountKeeper.SetAccount(suite.ctx, + suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)) + req = &types.QueryCurrentPubKeyEntryRequest{Address: addr.String()} + }, + true, + func(res *types.QueryCurrentPubKeyEntryResponse) { + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.Entry.PubKey), nil) + }, + }, + { + "query with more history", + func() { + suite.app.AccountKeeper.SetAccount(suite.ctx, suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)) + suite.ChangeAccountPubKeys(addr, pub1, pub2) + req = &types.QueryCurrentPubKeyEntryRequest{Address: addr.String()} + }, + true, + func(res *types.QueryCurrentPubKeyEntryResponse) { + suite.Require().Equal(types.DecodePubKey(suite.app.AppCodec(), res.Entry.PubKey), pub2) + }, + }, + } + + for _, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + tc.malleate() + ctx := sdk.WrapSDKContext(suite.ctx) + + res, err := suite.queryClient.CurrentPubKeyEntry(ctx, req) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + } else { + suite.Require().Error(err) + suite.Require().Nil(res) + } + + tc.posttests(res) + }) + } +} diff --git a/x/auth/changepubkey/keeper/keeper.go b/x/auth/changepubkey/keeper/keeper.go new file mode 100644 index 000000000000..aa369e52ba1f --- /dev/null +++ b/x/auth/changepubkey/keeper/keeper.go @@ -0,0 +1,150 @@ +package keeper + +import ( + "fmt" + "time" + + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" +) + +// Keeper manages history of public keys per account +type Keeper struct { + key sdk.StoreKey + cdc codec.BinaryMarshaler + ak authkeeper.AccountKeeper +} + +// NewKeeper returns a new keeper which manages pubkey history per account. +func NewKeeper( + cdc codec.BinaryMarshaler, key sdk.StoreKey, ak authkeeper.AccountKeeper, +) Keeper { + + return Keeper{key, cdc, ak} +} + +// "Everytime a key for an address is changed, we will store a log of this change in the state of the chain, +// thus creating a stack of all previous keys for an address and the time intervals for which they were active. +// This allows dapps and clients to easily query past keys for an account which may be useful for features +// such as verifying timestamped off-chain signed messages." + +// Logger returns a module-specific logger. +func (pk Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +// GetPubKeyHistory Returns the PubKey history of the account at address by time: involves current pubkey +func (pk Keeper) GetPubKeyHistory(ctx sdk.Context, addr sdk.AccAddress) ([]types.PubKeyHistory, error) { + entries := []types.PubKeyHistory{} + if pk.ak.GetAccount(ctx, addr) == nil { + return entries, fmt.Errorf("account %s not found", addr.String()) + } + iterator := pk.PubKeyHistoryIterator(ctx, addr) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + entry := types.DecodeHistoricalEntry(pk.cdc, iterator.Value()) + entries = append(entries, entry) + } + currentEntry := pk.GetCurrentPubKeyEntry(ctx, addr) + entries = append(entries, currentEntry) + return entries, nil +} + +// GetPubKeyHistoricalEntry Returns the PubKey historical entry at a specific time: involves current pubkey +func (pk Keeper) GetPubKeyHistoricalEntry(ctx sdk.Context, addr sdk.AccAddress, time time.Time) types.PubKeyHistory { + iterator := pk.PubKeyHistoryIteratorAfter(ctx, addr, time) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + entry := types.DecodeHistoricalEntry(pk.cdc, iterator.Value()) + if entry.EndTime.After(time) || entry.EndTime.Equal(time) { // TODO: is this inclusive? + return entry + } + } + + return pk.GetCurrentPubKeyEntry(ctx, addr) +} + +// GetLastPubKeyHistoricalEntry Returns the PubKey historical entry of last pubkey: does not involve current pubkey +func (pk Keeper) GetLastPubKeyHistoricalEntry(ctx sdk.Context, addr sdk.AccAddress) types.PubKeyHistory { + iterator := pk.PubKeyHistoryReverseIterator(ctx, addr) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + entry := types.DecodeHistoricalEntry(pk.cdc, iterator.Value()) + return entry + } + return types.PubKeyHistory{ + StartTime: time.Time{}, + EndTime: time.Time{}, + } +} + +// GetCurrentPubKeyEntry Returns the PubKey entry of current time +func (pk Keeper) GetCurrentPubKeyEntry(ctx sdk.Context, addr sdk.AccAddress) types.PubKeyHistory { + time := ctx.BlockTime() // TODO: ctx.BlockTime() is correct for endTime? + acc := pk.ak.GetAccount(ctx, addr) + lastEntry := pk.GetLastPubKeyHistoricalEntry(ctx, addr) + st := lastEntry.EndTime + if st.Equal(time) { + st = lastEntry.GetStartTime() + } + var pubkey crypto.PubKey + if acc != nil { + pubkey = acc.GetPubKey() + } + + return types.PubKeyHistory{ + PubKey: types.EncodePubKey(pk.cdc, pubkey), + StartTime: st, + EndTime: time, + } +} + +// StoreLastPubKey Store pubkey of an account at the time of changepubkey action +func (pk Keeper) StoreLastPubKey(ctx sdk.Context, addr sdk.AccAddress, time time.Time, pubkey crypto.PubKey) error { + store := ctx.KVStore(pk.key) + prefixStore := prefix.NewStore(store, addr) // prefix store for specific account + key := types.GetPubKeyHistoryKey(time) + lastEntry := pk.GetLastPubKeyHistoricalEntry(ctx, addr) + st := lastEntry.EndTime + if st.Equal(time) { + st = lastEntry.GetStartTime() + } + prefixStore.Set(key, types.EncodeHistoricalEntry(pk.cdc, types.PubKeyHistory{ + PubKey: types.EncodePubKey(pk.cdc, pubkey), + StartTime: st, + EndTime: time, + })) + return nil +} + +// PubKeyHistoryIteratorAfter returns the iterator used for getting a set of history +// where pubkey endTime is after a specific time +func (pk Keeper) PubKeyHistoryIteratorAfter(ctx sdk.Context, addr sdk.AccAddress, time time.Time) sdk.Iterator { + store := ctx.KVStore(pk.key) + prefixStore := prefix.NewStore(store, addr) // prefix store for specific account + startKey := types.GetPubKeyHistoryKey(time) + endKey := storetypes.PrefixEndBytes(types.KeyPrefixPubKeyHistory) + return prefixStore.Iterator(startKey, endKey) +} + +// PubKeyHistoryIterator returns the iterator used for getting a full history +func (pk Keeper) PubKeyHistoryIterator(ctx sdk.Context, addr sdk.AccAddress) sdk.Iterator { + store := ctx.KVStore(pk.key) + prefixStore := prefix.NewStore(store, addr) // prefix store for specific account + return sdk.KVStorePrefixIterator(prefixStore, types.KeyPrefixPubKeyHistory) +} + +// PubKeyHistoryReverseIterator returns the iterator used for getting a full history in reverse order +func (pk Keeper) PubKeyHistoryReverseIterator(ctx sdk.Context, addr sdk.AccAddress) sdk.Iterator { + store := ctx.KVStore(pk.key) + prefixStore := prefix.NewStore(store, addr) // prefix store for specific account + endKey := storetypes.PrefixEndBytes(types.KeyPrefixPubKeyHistory) + return prefixStore.ReverseIterator(types.KeyPrefixPubKeyHistory, endKey) +} diff --git a/x/auth/changepubkey/keeper/keeper_test.go b/x/auth/changepubkey/keeper/keeper_test.go new file mode 100644 index 000000000000..43bb32b9ff9a --- /dev/null +++ b/x/auth/changepubkey/keeper/keeper_test.go @@ -0,0 +1,128 @@ +package keeper_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/crypto" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/keeper" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +type KeeperTestSuite struct { + suite.Suite + + app *simapp.SimApp + ctx sdk.Context + + queryClient types.QueryClient +} + +// returns context and app with params set on account keeper +func createTestApp(isCheckTx bool) (*simapp.SimApp, sdk.Context) { + app := simapp.Setup(isCheckTx) + ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{Time: time.Now()}) + app.AccountKeeper.SetParams(ctx, authtypes.DefaultParams()) + + return app, ctx +} + +func (suite *KeeperTestSuite) SetupTest() { + suite.app, suite.ctx = createTestApp(true) + + queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.app.InterfaceRegistry()) + types.RegisterQueryServer(queryHelper, suite.app.AccountHistoryKeeper) + suite.queryClient = types.NewQueryClient(queryHelper) +} + +func (suite *KeeperTestSuite) ChangeAccountPubKeys(addr sdk.AccAddress, pubkeys ...crypto.PubKey) { + suite.app.AccountKeeper.SetAccount(suite.ctx, suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)) + + for _, pub := range pubkeys { + msgServer := keeper.NewMsgServerImpl(suite.app.AccountKeeper, suite.app.AccountHistoryKeeper) + _, err := msgServer.ChangePubKey(sdk.WrapSDKContext(suite.ctx), types.NewMsgChangePubKey(addr, pub)) + suite.Require().NoError(err) + suite.ctx = suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(time.Minute)) + } +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func TestPubKeyHistory_StoreGet(t *testing.T) { + app, ctx := createTestApp(true) + cdc := app.AppCodec() + + addr1 := sdk.AccAddress([]byte("addr1---------------")) + + currentTime := ctx.BlockTime() + // create accounts + acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr1) + app.AccountKeeper.SetAccount(ctx, acc) + + // store pubkey when pubkey does not exist + app.AccountHistoryKeeper.StoreLastPubKey(ctx, addr1, currentTime.Truncate(time.Hour), acc.GetPubKey()) + + _, pub1, _ := testdata.KeyTestPubAddr() + acc.SetPubKey(pub1) + app.AccountKeeper.SetAccount(ctx, acc) + + // Note: store pubkey when pubkey does exist, it will overwrite previous one + // since previous one's endtime = current one's endtime + app.AccountHistoryKeeper.StoreLastPubKey(ctx, addr1, currentTime.Truncate(time.Hour), acc.GetPubKey()) + + // store pubkey after pubkey is set + _, pub2, _ := testdata.KeyTestPubAddr() + acc.SetPubKey(pub2) + app.AccountKeeper.SetAccount(ctx, acc) + + app.AccountHistoryKeeper.StoreLastPubKey(ctx, addr1, currentTime.Truncate(time.Minute), acc.GetPubKey()) + _, pub3, _ := testdata.KeyTestPubAddr() + acc.SetPubKey(pub3) + app.AccountKeeper.SetAccount(ctx, acc) + + // try iteration after changing pubkey 3 times + history, err := app.AccountHistoryKeeper.GetPubKeyHistory(ctx, addr1) + require.NoError(t, err) + require.Equal(t, len(history), 3) + + require.Equal(t, history[0].StartTime, time.Time{}) + require.Equal(t, history[0].EndTime, currentTime.Truncate(time.Hour)) + require.Equal(t, types.DecodePubKey(cdc, history[0].GetPubKey()).Address(), pub1.Address()) + + require.Equal(t, history[1].StartTime, currentTime.Truncate(time.Hour)) + require.Equal(t, history[1].EndTime, currentTime.Truncate(time.Minute)) + require.Equal(t, types.DecodePubKey(cdc, history[1].GetPubKey()).Address(), pub2.Address()) + + require.Equal(t, history[2].StartTime, currentTime.Truncate(time.Minute)) + require.Equal(t, history[2].EndTime, currentTime) + require.Equal(t, types.DecodePubKey(cdc, history[2].GetPubKey()).Address(), pub3.Address()) + + history1 := app.AccountHistoryKeeper.GetPubKeyHistoricalEntry(ctx, addr1, currentTime.Truncate(2*time.Hour)) + require.Equal(t, history1, history[0]) + history2 := app.AccountHistoryKeeper.GetPubKeyHistoricalEntry(ctx, addr1, currentTime.Truncate(time.Hour)) + require.Equal(t, history2, history[0]) + history3 := app.AccountHistoryKeeper.GetPubKeyHistoricalEntry(ctx, addr1, currentTime.Truncate(2*time.Minute)) + require.Equal(t, history3, history[1]) + history4 := app.AccountHistoryKeeper.GetPubKeyHistoricalEntry(ctx, addr1, currentTime.Truncate(time.Minute)) + require.Equal(t, history4, history[1]) + history5 := app.AccountHistoryKeeper.GetPubKeyHistoricalEntry(ctx, addr1, currentTime.Truncate(time.Second)) + require.Equal(t, history5, history[2]) + history6 := app.AccountHistoryKeeper.GetPubKeyHistoricalEntry(ctx, addr1, currentTime) + require.Equal(t, history6, history[2]) + history7 := app.AccountHistoryKeeper.GetLastPubKeyHistoricalEntry(ctx, addr1) + require.Equal(t, history7, history[1]) + history8 := app.AccountHistoryKeeper.GetCurrentPubKeyEntry(ctx, addr1) + require.Equal(t, history8, history[2]) +} diff --git a/x/auth/changepubkey/keeper/msg_server.go b/x/auth/changepubkey/keeper/msg_server.go new file mode 100644 index 000000000000..5131469328ce --- /dev/null +++ b/x/auth/changepubkey/keeper/msg_server.go @@ -0,0 +1,59 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" +) + +type msgServer struct { + authkeeper.AccountKeeper + historyKeeper Keeper +} + +// NewMsgServerImpl returns an implementation of the changepubkey MsgServer interface, +// wrapping the corresponding AccountKeeper. +func NewMsgServerImpl(k authkeeper.AccountKeeper, historyKeeper Keeper) types.MsgServer { + return &msgServer{k, historyKeeper} +} + +var _ types.MsgServer = msgServer{} + +func (s msgServer) ChangePubKey(goCtx context.Context, msg *types.MsgChangePubKey) (*types.MsgChangePubKeyResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + ak := s.AccountKeeper + + acc := ak.GetAccount(ctx, msg.Address) + if acc == nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "account %s does not exist", msg.Address) + } + // TODO: what time would be good to be put here? + s.historyKeeper.StoreLastPubKey(ctx, msg.Address, ctx.BlockTime(), acc.GetPubKey()) + + acc.SetPubKey(msg.GetPubKey()) + ak.SetAccount(ctx, acc) + + // handle additional fee logic inside MsgChangePubKey handler + signers := msg.GetSigners() + if len(signers) == 0 { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "signers should exist") + } + + authParams := ak.GetParams(ctx) + if !authParams.EnableChangePubKey { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "change pubkey param is disabled") + } + ctx.GasMeter().ConsumeGas(authParams.PubKeyChangeCost, "pubkey change fee") + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + ) + + return &types.MsgChangePubKeyResponse{}, nil +} diff --git a/x/auth/changepubkey/module.go b/x/auth/changepubkey/module.go new file mode 100644 index 000000000000..261106d1c5f7 --- /dev/null +++ b/x/auth/changepubkey/module.go @@ -0,0 +1,132 @@ +package changepubkey + +import ( + "encoding/json" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/client/cli" + changepubkeykeeper "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/keeper" + "github.com/cosmos/cosmos-sdk/x/auth/changepubkey/types" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the sub-pubkey +// module. The module itself contain no special logic or state other than message +// handling. +type AppModuleBasic struct{} + +// Name returns the module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the module's types with the given codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) +} + +// RegisterInterfaces registers the module's interfaces and implementations with +// the given interface registry. +func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + types.RegisterInterfaces(registry) +} + +// DefaultGenesis returns the module's default genesis state as raw bytes. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage { + return []byte("{}") +} + +// ValidateGenesis performs genesis state validation. Currently, this is a no-op. +func (AppModuleBasic) ValidateGenesis(_ codec.JSONMarshaler, _ client.TxEncodingConfig, bz json.RawMessage) error { + return nil +} + +// RegisterRESTRoutes registers module's REST handlers. Currently, this is a no-op. +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} + +// RegisterGRPCGatewayRoutes registers the module's gRPC Gateway routes. Currently, this +// is a no-op. +func (a AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {} + +// GetTxCmd returns the root tx command for the auth module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the module's root query command. Currently, this is a no-op. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return nil +} + +// AppModule extends the AppModuleBasic implementation by implementing the +// AppModule interface. +type AppModule struct { + AppModuleBasic + + accountKeeper keeper.AccountKeeper + historyKeeper changepubkeykeeper.Keeper +} + +// NewAppModule returns an instance of AppModule +func NewAppModule(ak keeper.AccountKeeper, hk changepubkeykeeper.Keeper) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + accountKeeper: ak, + historyKeeper: hk, + } +} + +// RegisterInvariants performs a no-op; there are no invariants to enforce. +func (AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// Route returns the module's message router and handler. +func (am AppModule) Route() sdk.Route { + return sdk.NewRoute(types.RouterKey, NewHandler(am.accountKeeper, am.historyKeeper)) +} + +// QuerierRoute returns querier route for changepubkey +func (AppModule) QuerierRoute() string { + return types.QuerierRoute +} + +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), changepubkeykeeper.NewMsgServerImpl(am.accountKeeper, am.historyKeeper)) +} + +// LegacyQuerierHandler performs a no-op. +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return nil +} + +// InitGenesis performs a no-op. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data json.RawMessage) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// BeginBlock performs a no-op. +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} + +// EndBlock performs a no-op. +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ExportGenesis is always empty, as InitGenesis does nothing either. +func (am AppModule) ExportGenesis(_ sdk.Context, cdc codec.JSONMarshaler) json.RawMessage { + return []byte("{}") +} diff --git a/x/auth/changepubkey/types/codec.go b/x/auth/changepubkey/types/codec.go new file mode 100644 index 000000000000..bb279a1d537f --- /dev/null +++ b/x/auth/changepubkey/types/codec.go @@ -0,0 +1,33 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +// RegisterLegacyAminoCodec registers the changepubkey interfaces and concrete types on the +// provided LegacyAmino codec. These types are used for Amino JSON serialization +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgChangePubKey{}, "cosmos-sdk/MsgChangePubKey", nil) + cdc.RegisterConcrete(&PubKeyHistory{}, "cosmos-sdk/PubKeyHistory", nil) +} + +// RegisterInterfaces register interfaces for changepubkey module +func RegisterInterfaces(registry types.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgChangePubKey{}, + ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var amino = codec.NewLegacyAmino() + +func init() { + RegisterLegacyAminoCodec(amino) + cryptocodec.RegisterCrypto(amino) + + amino.Seal() +} diff --git a/x/auth/changepubkey/types/common_test.go b/x/auth/changepubkey/types/common_test.go new file mode 100644 index 000000000000..4f361059ad3c --- /dev/null +++ b/x/auth/changepubkey/types/common_test.go @@ -0,0 +1,10 @@ +package types_test + +import ( + "github.com/cosmos/cosmos-sdk/simapp" +) + +var ( + app = simapp.Setup(false) + appCodec, _ = simapp.MakeCodecs() +) diff --git a/x/auth/changepubkey/types/keys.go b/x/auth/changepubkey/types/keys.go new file mode 100644 index 000000000000..c9e302d2a6bd --- /dev/null +++ b/x/auth/changepubkey/types/keys.go @@ -0,0 +1,48 @@ +package types + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// constants +var ( + // module name + ModuleName = "changepubkey" + + // StoreKey is string representation of the store key for changepubkey + StoreKey = ModuleName + + // QuerierRoute is the querier route for changepubkey + QuerierRoute = ModuleName + + // AttributeValueCategory is an alias for the message event value. + AttributeValueCategory = ModuleName + + // RouterKey defines the module's message routing key + RouterKey = ModuleName + + // KeyPrefixPubKeyHistory defines history of PubKey history of an account + KeyPrefixPubKeyHistory = []byte{0x01} // prefix for the timestamps in pubkey history queue +) + +// GetPubKeyHistoryKey returns the prefix key used for getting a set of history +// where pubkey endTime is after a specific time +func GetPubKeyHistoryKey(timestamp time.Time) []byte { + timeBz := sdk.FormatTimeBytes(timestamp) + timeBzL := len(timeBz) + prefixL := len(KeyPrefixPubKeyHistory) + + bz := make([]byte, prefixL+8+timeBzL) + + // copy the prefix + copy(bz[:prefixL], KeyPrefixPubKeyHistory) + + // copy the encoded time bytes length + copy(bz[prefixL:prefixL+8], sdk.Uint64ToBigEndian(uint64(timeBzL))) + + // copy the encoded time bytes + copy(bz[prefixL+8:prefixL+8+timeBzL], timeBz) + return bz +} diff --git a/x/auth/changepubkey/types/msgs.go b/x/auth/changepubkey/types/msgs.go new file mode 100644 index 000000000000..783963ba1352 --- /dev/null +++ b/x/auth/changepubkey/types/msgs.go @@ -0,0 +1,76 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/tendermint/tendermint/crypto" +) + +// TypeMsgChangePubKey defines the type value for a MsgChangePubKey. +const TypeMsgChangePubKey = "msg_change_pubkey" + +var _ sdk.Msg = &MsgChangePubKey{} + +// NewMsgChangePubKey returns a reference to a new MsgChangePubKey. +func NewMsgChangePubKey(address sdk.AccAddress, pubKey crypto.PubKey) *MsgChangePubKey { + msg := MsgChangePubKey{ + Address: address, + } + msg.SetPubKey(pubKey) + return &msg +} + +// Route returns the message route for a MsgChangePubKey. +func (msg MsgChangePubKey) Route() string { return RouterKey } + +// Type returns the message type for a MsgChangePubKey. +func (msg MsgChangePubKey) Type() string { return TypeMsgChangePubKey } + +// ValidateBasic Implements Msg. +func (msg MsgChangePubKey) ValidateBasic() error { + if err := sdk.VerifyAddressFormat(msg.Address); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid sender address: %s", err) + } + + if len(msg.PubKey) == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, "pubkey should not be empty") + } + + if len(msg.GetPubKey().Address()) == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidPubKey, "pubkey should be able to associated to a valid address") + } + + return nil +} + +// GetSignBytes returns the bytes all expected signers must sign over for a +// MsgChangePubKey. +func (msg MsgChangePubKey) GetSignBytes() []byte { + return sdk.MustSortJSON(amino.MustMarshalJSON(&msg)) +} + +// GetSigners returns the expected signers for a MsgChangePubKey. +func (msg MsgChangePubKey) GetSigners() []sdk.AccAddress { + return []sdk.AccAddress{msg.Address} +} + +// GetPubKey returns public key +func (msg MsgChangePubKey) GetPubKey() (pk crypto.PubKey) { + if len(msg.PubKey) == 0 { + return nil + } + + amino.MustUnmarshalBinaryBare(msg.PubKey, &pk) + return pk +} + +// SetPubKey set public key +func (msg *MsgChangePubKey) SetPubKey(pubKey crypto.PubKey) error { + if pubKey == nil { + msg.PubKey = nil + } else { + msg.PubKey = amino.MustMarshalBinaryBare(pubKey) + } + + return nil +} diff --git a/x/auth/changepubkey/types/pubkey_history.go b/x/auth/changepubkey/types/pubkey_history.go new file mode 100644 index 000000000000..549db8bbc4d6 --- /dev/null +++ b/x/auth/changepubkey/types/pubkey_history.go @@ -0,0 +1,39 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/tendermint/tendermint/crypto" +) + +func EncodePubKey(cdc codec.BinaryMarshaler, pubkey crypto.PubKey) []byte { + if pubkey == nil { + return []byte{} + } + bz, err := codec.MarshalAny(cdc, pubkey) + if err != nil { + panic(err) + } + return bz +} + +func DecodePubKey(cdc codec.BinaryMarshaler, bz []byte) crypto.PubKey { + if len(bz) == 0 { + return nil + } + var pubkey crypto.PubKey + err := codec.UnmarshalAny(cdc, &pubkey, bz) + if err != nil { + panic(err) + } + return pubkey +} + +func EncodeHistoricalEntry(cdc codec.BinaryMarshaler, entry PubKeyHistory) []byte { + return cdc.MustMarshalBinaryBare(&entry) +} + +func DecodeHistoricalEntry(cdc codec.BinaryMarshaler, bz []byte) PubKeyHistory { + var entry PubKeyHistory + cdc.MustUnmarshalBinaryBare(bz, &entry) + return entry +} diff --git a/x/auth/changepubkey/types/pubkey_history.pb.go b/x/auth/changepubkey/types/pubkey_history.pb.go new file mode 100644 index 000000000000..f0570ef7c458 --- /dev/null +++ b/x/auth/changepubkey/types/pubkey_history.pb.go @@ -0,0 +1,2124 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/changepubkey/v1beta1/pubkey_history.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + _ "github.com/golang/protobuf/ptypes/timestamp" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" + time "time" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf +var _ = time.Kitchen + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type PubKeyHistory struct { + PubKey []byte `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"public_key,omitempty" yaml:"public_key"` + StartTime time.Time `protobuf:"bytes,2,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time" yaml:"start_time"` + EndTime time.Time `protobuf:"bytes,3,opt,name=end_time,json=endTime,proto3,stdtime" json:"end_time" yaml:"end_time"` +} + +func (m *PubKeyHistory) Reset() { *m = PubKeyHistory{} } +func (m *PubKeyHistory) String() string { return proto.CompactTextString(m) } +func (*PubKeyHistory) ProtoMessage() {} +func (*PubKeyHistory) Descriptor() ([]byte, []int) { + return fileDescriptor_60a6d0a8f3ff57e6, []int{0} +} +func (m *PubKeyHistory) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PubKeyHistory) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PubKeyHistory.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 *PubKeyHistory) XXX_Merge(src proto.Message) { + xxx_messageInfo_PubKeyHistory.Merge(m, src) +} +func (m *PubKeyHistory) XXX_Size() int { + return m.Size() +} +func (m *PubKeyHistory) XXX_DiscardUnknown() { + xxx_messageInfo_PubKeyHistory.DiscardUnknown(m) +} + +var xxx_messageInfo_PubKeyHistory proto.InternalMessageInfo + +func (m *PubKeyHistory) GetPubKey() []byte { + if m != nil { + return m.PubKey + } + return nil +} + +func (m *PubKeyHistory) GetStartTime() time.Time { + if m != nil { + return m.StartTime + } + return time.Time{} +} + +func (m *PubKeyHistory) GetEndTime() time.Time { + if m != nil { + return m.EndTime + } + return time.Time{} +} + +// QueryPubKeyHistoryRequest is the request type for the Query/PubKeyHistory RPC method. +type QueryPubKeyHistoryRequest struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *QueryPubKeyHistoryRequest) Reset() { *m = QueryPubKeyHistoryRequest{} } +func (m *QueryPubKeyHistoryRequest) String() string { return proto.CompactTextString(m) } +func (*QueryPubKeyHistoryRequest) ProtoMessage() {} +func (*QueryPubKeyHistoryRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_60a6d0a8f3ff57e6, []int{1} +} +func (m *QueryPubKeyHistoryRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPubKeyHistoryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPubKeyHistoryRequest.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 *QueryPubKeyHistoryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPubKeyHistoryRequest.Merge(m, src) +} +func (m *QueryPubKeyHistoryRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryPubKeyHistoryRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPubKeyHistoryRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPubKeyHistoryRequest proto.InternalMessageInfo + +func (m *QueryPubKeyHistoryRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +// QueryPubKeyHistoryResponse is the response type for the Query/PubKeyHistory RPC method. +type QueryPubKeyHistoryResponse struct { + History []PubKeyHistory `protobuf:"bytes,1,rep,name=history,proto3" json:"history"` +} + +func (m *QueryPubKeyHistoryResponse) Reset() { *m = QueryPubKeyHistoryResponse{} } +func (m *QueryPubKeyHistoryResponse) String() string { return proto.CompactTextString(m) } +func (*QueryPubKeyHistoryResponse) ProtoMessage() {} +func (*QueryPubKeyHistoryResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_60a6d0a8f3ff57e6, []int{2} +} +func (m *QueryPubKeyHistoryResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPubKeyHistoryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPubKeyHistoryResponse.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 *QueryPubKeyHistoryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPubKeyHistoryResponse.Merge(m, src) +} +func (m *QueryPubKeyHistoryResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryPubKeyHistoryResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPubKeyHistoryResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPubKeyHistoryResponse proto.InternalMessageInfo + +func (m *QueryPubKeyHistoryResponse) GetHistory() []PubKeyHistory { + if m != nil { + return m.History + } + return nil +} + +// QueryPubKeyHistoricalEntryRequest is the request type for the Query/PubKeyHistoricalEntry RPC method. +type QueryPubKeyHistoricalEntryRequest struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + Time time.Time `protobuf:"bytes,2,opt,name=time,proto3,stdtime" json:"time" yaml:"time"` +} + +func (m *QueryPubKeyHistoricalEntryRequest) Reset() { *m = QueryPubKeyHistoricalEntryRequest{} } +func (m *QueryPubKeyHistoricalEntryRequest) String() string { return proto.CompactTextString(m) } +func (*QueryPubKeyHistoricalEntryRequest) ProtoMessage() {} +func (*QueryPubKeyHistoricalEntryRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_60a6d0a8f3ff57e6, []int{3} +} +func (m *QueryPubKeyHistoricalEntryRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPubKeyHistoricalEntryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPubKeyHistoricalEntryRequest.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 *QueryPubKeyHistoricalEntryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPubKeyHistoricalEntryRequest.Merge(m, src) +} +func (m *QueryPubKeyHistoricalEntryRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryPubKeyHistoricalEntryRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPubKeyHistoricalEntryRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPubKeyHistoricalEntryRequest proto.InternalMessageInfo + +func (m *QueryPubKeyHistoricalEntryRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *QueryPubKeyHistoricalEntryRequest) GetTime() time.Time { + if m != nil { + return m.Time + } + return time.Time{} +} + +// QueryPubKeyHistoricalEntryResponse is the response type for the Query/PubKeyHistoricalEntry RPC method. +type QueryPubKeyHistoricalEntryResponse struct { + Entry PubKeyHistory `protobuf:"bytes,1,opt,name=entry,proto3" json:"entry"` +} + +func (m *QueryPubKeyHistoricalEntryResponse) Reset() { *m = QueryPubKeyHistoricalEntryResponse{} } +func (m *QueryPubKeyHistoricalEntryResponse) String() string { return proto.CompactTextString(m) } +func (*QueryPubKeyHistoricalEntryResponse) ProtoMessage() {} +func (*QueryPubKeyHistoricalEntryResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_60a6d0a8f3ff57e6, []int{4} +} +func (m *QueryPubKeyHistoricalEntryResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPubKeyHistoricalEntryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPubKeyHistoricalEntryResponse.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 *QueryPubKeyHistoricalEntryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPubKeyHistoricalEntryResponse.Merge(m, src) +} +func (m *QueryPubKeyHistoricalEntryResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryPubKeyHistoricalEntryResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPubKeyHistoricalEntryResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPubKeyHistoricalEntryResponse proto.InternalMessageInfo + +func (m *QueryPubKeyHistoricalEntryResponse) GetEntry() PubKeyHistory { + if m != nil { + return m.Entry + } + return PubKeyHistory{} +} + +// QueryLastPubKeyHistoricalEntryRequest is the request type for the Query/LastPubKeyHistoricalEntry RPC method. +type QueryLastPubKeyHistoricalEntryRequest struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *QueryLastPubKeyHistoricalEntryRequest) Reset() { *m = QueryLastPubKeyHistoricalEntryRequest{} } +func (m *QueryLastPubKeyHistoricalEntryRequest) String() string { return proto.CompactTextString(m) } +func (*QueryLastPubKeyHistoricalEntryRequest) ProtoMessage() {} +func (*QueryLastPubKeyHistoricalEntryRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_60a6d0a8f3ff57e6, []int{5} +} +func (m *QueryLastPubKeyHistoricalEntryRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryLastPubKeyHistoricalEntryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryLastPubKeyHistoricalEntryRequest.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 *QueryLastPubKeyHistoricalEntryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryLastPubKeyHistoricalEntryRequest.Merge(m, src) +} +func (m *QueryLastPubKeyHistoricalEntryRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryLastPubKeyHistoricalEntryRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryLastPubKeyHistoricalEntryRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryLastPubKeyHistoricalEntryRequest proto.InternalMessageInfo + +func (m *QueryLastPubKeyHistoricalEntryRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +// QueryLastPubKeyHistoricalEntryResponse is the response type for the Query/LastPubKeyHistoricalEntry RPC method. +type QueryLastPubKeyHistoricalEntryResponse struct { + Entry PubKeyHistory `protobuf:"bytes,1,opt,name=entry,proto3" json:"entry"` +} + +func (m *QueryLastPubKeyHistoricalEntryResponse) Reset() { + *m = QueryLastPubKeyHistoricalEntryResponse{} +} +func (m *QueryLastPubKeyHistoricalEntryResponse) String() string { return proto.CompactTextString(m) } +func (*QueryLastPubKeyHistoricalEntryResponse) ProtoMessage() {} +func (*QueryLastPubKeyHistoricalEntryResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_60a6d0a8f3ff57e6, []int{6} +} +func (m *QueryLastPubKeyHistoricalEntryResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryLastPubKeyHistoricalEntryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryLastPubKeyHistoricalEntryResponse.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 *QueryLastPubKeyHistoricalEntryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryLastPubKeyHistoricalEntryResponse.Merge(m, src) +} +func (m *QueryLastPubKeyHistoricalEntryResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryLastPubKeyHistoricalEntryResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryLastPubKeyHistoricalEntryResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryLastPubKeyHistoricalEntryResponse proto.InternalMessageInfo + +func (m *QueryLastPubKeyHistoricalEntryResponse) GetEntry() PubKeyHistory { + if m != nil { + return m.Entry + } + return PubKeyHistory{} +} + +// QueryCurrentPubKeyEntryRequest is the request type for the Query/CurrentPubKeyEntry RPC method. +type QueryCurrentPubKeyEntryRequest struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *QueryCurrentPubKeyEntryRequest) Reset() { *m = QueryCurrentPubKeyEntryRequest{} } +func (m *QueryCurrentPubKeyEntryRequest) String() string { return proto.CompactTextString(m) } +func (*QueryCurrentPubKeyEntryRequest) ProtoMessage() {} +func (*QueryCurrentPubKeyEntryRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_60a6d0a8f3ff57e6, []int{7} +} +func (m *QueryCurrentPubKeyEntryRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryCurrentPubKeyEntryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryCurrentPubKeyEntryRequest.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 *QueryCurrentPubKeyEntryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryCurrentPubKeyEntryRequest.Merge(m, src) +} +func (m *QueryCurrentPubKeyEntryRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryCurrentPubKeyEntryRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryCurrentPubKeyEntryRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryCurrentPubKeyEntryRequest proto.InternalMessageInfo + +func (m *QueryCurrentPubKeyEntryRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +// QueryCurrentPubKeyEntryResponse is the response type for the Query/LastPubKeyHistoricalEntry RPC method. +type QueryCurrentPubKeyEntryResponse struct { + Entry PubKeyHistory `protobuf:"bytes,1,opt,name=entry,proto3" json:"entry"` +} + +func (m *QueryCurrentPubKeyEntryResponse) Reset() { *m = QueryCurrentPubKeyEntryResponse{} } +func (m *QueryCurrentPubKeyEntryResponse) String() string { return proto.CompactTextString(m) } +func (*QueryCurrentPubKeyEntryResponse) ProtoMessage() {} +func (*QueryCurrentPubKeyEntryResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_60a6d0a8f3ff57e6, []int{8} +} +func (m *QueryCurrentPubKeyEntryResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryCurrentPubKeyEntryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryCurrentPubKeyEntryResponse.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 *QueryCurrentPubKeyEntryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryCurrentPubKeyEntryResponse.Merge(m, src) +} +func (m *QueryCurrentPubKeyEntryResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryCurrentPubKeyEntryResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryCurrentPubKeyEntryResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryCurrentPubKeyEntryResponse proto.InternalMessageInfo + +func (m *QueryCurrentPubKeyEntryResponse) GetEntry() PubKeyHistory { + if m != nil { + return m.Entry + } + return PubKeyHistory{} +} + +func init() { + proto.RegisterType((*PubKeyHistory)(nil), "cosmos.changepubkey.v1beta1.PubKeyHistory") + proto.RegisterType((*QueryPubKeyHistoryRequest)(nil), "cosmos.changepubkey.v1beta1.QueryPubKeyHistoryRequest") + proto.RegisterType((*QueryPubKeyHistoryResponse)(nil), "cosmos.changepubkey.v1beta1.QueryPubKeyHistoryResponse") + proto.RegisterType((*QueryPubKeyHistoricalEntryRequest)(nil), "cosmos.changepubkey.v1beta1.QueryPubKeyHistoricalEntryRequest") + proto.RegisterType((*QueryPubKeyHistoricalEntryResponse)(nil), "cosmos.changepubkey.v1beta1.QueryPubKeyHistoricalEntryResponse") + proto.RegisterType((*QueryLastPubKeyHistoricalEntryRequest)(nil), "cosmos.changepubkey.v1beta1.QueryLastPubKeyHistoricalEntryRequest") + proto.RegisterType((*QueryLastPubKeyHistoricalEntryResponse)(nil), "cosmos.changepubkey.v1beta1.QueryLastPubKeyHistoricalEntryResponse") + proto.RegisterType((*QueryCurrentPubKeyEntryRequest)(nil), "cosmos.changepubkey.v1beta1.QueryCurrentPubKeyEntryRequest") + proto.RegisterType((*QueryCurrentPubKeyEntryResponse)(nil), "cosmos.changepubkey.v1beta1.QueryCurrentPubKeyEntryResponse") +} + +func init() { + proto.RegisterFile("cosmos/changepubkey/v1beta1/pubkey_history.proto", fileDescriptor_60a6d0a8f3ff57e6) +} + +var fileDescriptor_60a6d0a8f3ff57e6 = []byte{ + // 669 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x4f, 0x4f, 0x13, 0x4f, + 0x18, 0xee, 0xf0, 0xaf, 0x3f, 0x86, 0x9f, 0x31, 0x4e, 0x30, 0x96, 0x45, 0xb7, 0x38, 0x89, 0x86, + 0x18, 0xd9, 0x15, 0x0c, 0x90, 0x80, 0x68, 0x6c, 0x03, 0x1a, 0xf1, 0x80, 0x8d, 0x07, 0xe3, 0xa5, + 0x99, 0x6d, 0xc7, 0x76, 0x43, 0x77, 0x67, 0xdd, 0x99, 0x35, 0x6e, 0x8c, 0x17, 0x13, 0x3d, 0x93, + 0x78, 0xf3, 0x5b, 0xf8, 0x09, 0xbc, 0x72, 0x24, 0xd1, 0x83, 0x27, 0x34, 0xe0, 0xc9, 0x9b, 0x7e, + 0x02, 0xb3, 0x33, 0xb3, 0x96, 0x02, 0xfd, 0x43, 0xe5, 0xb4, 0x3b, 0x33, 0xef, 0xf3, 0xbc, 0xcf, + 0xf3, 0xbe, 0xef, 0x0c, 0xbc, 0x51, 0x61, 0xdc, 0x63, 0xdc, 0xae, 0xd4, 0x89, 0x5f, 0xa3, 0x41, + 0xe4, 0x6c, 0xd2, 0xd8, 0x7e, 0x31, 0xeb, 0x50, 0x41, 0x66, 0x6d, 0xb5, 0x2c, 0xd7, 0x5d, 0x2e, + 0x58, 0x18, 0x5b, 0x41, 0xc8, 0x04, 0x43, 0x93, 0x0a, 0x61, 0x1d, 0x44, 0x58, 0x1a, 0x61, 0x8c, + 0xd7, 0x58, 0x8d, 0xc9, 0x38, 0x3b, 0xf9, 0x53, 0x10, 0x23, 0x5f, 0x63, 0xac, 0xd6, 0xa0, 0xb6, + 0x5c, 0x39, 0xd1, 0x33, 0x5b, 0xb8, 0x1e, 0xe5, 0x82, 0x78, 0x81, 0x0e, 0xb8, 0xa8, 0x03, 0x48, + 0xe0, 0xda, 0xc4, 0xf7, 0x99, 0x20, 0xc2, 0x65, 0x3e, 0x57, 0xa7, 0xf8, 0xed, 0x00, 0x3c, 0xb3, + 0x11, 0x39, 0xeb, 0x34, 0xbe, 0xaf, 0x94, 0xa0, 0x35, 0x98, 0x0d, 0x22, 0xa7, 0xbc, 0x49, 0xe3, + 0x1c, 0x98, 0x02, 0xd3, 0xff, 0x17, 0x66, 0x7e, 0xee, 0xe6, 0xc7, 0x83, 0xc8, 0x69, 0xb8, 0x95, + 0x64, 0xf7, 0x3a, 0xf3, 0x5c, 0x41, 0xbd, 0x40, 0xc4, 0xbf, 0x77, 0xf3, 0xe7, 0x62, 0xe2, 0x35, + 0x96, 0x70, 0xf3, 0x14, 0x97, 0x46, 0x02, 0x49, 0x87, 0x9e, 0x40, 0xc8, 0x05, 0x09, 0x45, 0x39, + 0x11, 0x94, 0x1b, 0x98, 0x02, 0xd3, 0x63, 0x73, 0x86, 0xa5, 0xc4, 0x58, 0xa9, 0x5a, 0xeb, 0x71, + 0xaa, 0xb6, 0x70, 0x69, 0x7b, 0x37, 0x9f, 0x69, 0x52, 0x36, 0xb1, 0x78, 0xeb, 0x5b, 0x1e, 0x94, + 0x46, 0xe5, 0x46, 0x12, 0x8e, 0x4a, 0xf0, 0x3f, 0xea, 0x57, 0x15, 0xef, 0x60, 0x57, 0xde, 0x49, + 0xcd, 0x7b, 0x56, 0xf1, 0xa6, 0x48, 0xc5, 0x9a, 0xa5, 0x7e, 0x35, 0x09, 0xc5, 0xf3, 0x70, 0xe2, + 0x51, 0x44, 0xc3, 0xb8, 0xa5, 0x16, 0x25, 0xfa, 0x3c, 0xa2, 0x5c, 0xa0, 0x1c, 0xcc, 0x92, 0x6a, + 0x35, 0xa4, 0x9c, 0xcb, 0x92, 0x8c, 0x96, 0xd2, 0x25, 0xae, 0x43, 0xe3, 0x38, 0x18, 0x0f, 0x98, + 0xcf, 0x29, 0x7a, 0x00, 0xb3, 0xba, 0xbf, 0x39, 0x30, 0x35, 0x38, 0x3d, 0x36, 0x77, 0xcd, 0xea, + 0xd0, 0x60, 0xab, 0x85, 0xa4, 0x30, 0x94, 0xe8, 0x2e, 0xa5, 0x04, 0xf8, 0x1d, 0x80, 0x97, 0x8f, + 0xa4, 0x72, 0x2b, 0xa4, 0xb1, 0xea, 0x8b, 0x1e, 0x94, 0xa2, 0x7b, 0x70, 0xa8, 0xc7, 0x46, 0x5c, + 0xd0, 0x05, 0x1b, 0x53, 0x05, 0x6b, 0x16, 0x4b, 0x12, 0xe0, 0x06, 0xc4, 0x9d, 0x74, 0x68, 0xeb, + 0x6b, 0x70, 0x98, 0x26, 0x1b, 0x52, 0x46, 0x3f, 0xc6, 0x15, 0x1c, 0xdf, 0x85, 0x57, 0x64, 0xb6, + 0x87, 0x84, 0x8b, 0xfe, 0x9c, 0xe3, 0x00, 0x5e, 0xed, 0x46, 0x71, 0xca, 0xa2, 0x97, 0xa0, 0x29, + 0x33, 0x16, 0xa3, 0x30, 0xa4, 0xbe, 0x4e, 0xda, 0xa3, 0x5a, 0x17, 0xe6, 0xdb, 0x62, 0x4f, 0x57, + 0xe6, 0xdc, 0xc7, 0x11, 0x38, 0x2c, 0x73, 0xa1, 0x4f, 0xe0, 0xf0, 0x2b, 0xb0, 0xd0, 0x91, 0xb4, + 0xed, 0x55, 0x31, 0x16, 0x4f, 0x8c, 0x53, 0xa6, 0xf0, 0xca, 0x9b, 0xcf, 0x3f, 0xde, 0x0f, 0x2c, + 0xa2, 0x79, 0xbb, 0xf7, 0x57, 0xd3, 0x7e, 0xa5, 0xab, 0xf6, 0x1a, 0x7d, 0x00, 0xf0, 0xfc, 0xb1, + 0xcd, 0x45, 0xb7, 0x4f, 0xa6, 0xe8, 0xf0, 0x60, 0x19, 0x77, 0xfa, 0xc6, 0x6b, 0x67, 0x19, 0xf4, + 0x0b, 0xc0, 0x89, 0xb6, 0xd3, 0x87, 0x0a, 0xdd, 0x13, 0x74, 0x9b, 0x7e, 0xa3, 0xf8, 0x4f, 0x1c, + 0x5a, 0xe8, 0xba, 0x6c, 0xc1, 0x2a, 0x2a, 0x76, 0x6c, 0x41, 0x83, 0x70, 0x51, 0x6e, 0xe9, 0x43, + 0xc2, 0x54, 0x96, 0x23, 0x75, 0xa0, 0x21, 0x5f, 0x00, 0x44, 0x47, 0x67, 0x18, 0x2d, 0x77, 0x17, + 0xda, 0xf6, 0xd6, 0x18, 0xb7, 0xfa, 0x03, 0x6b, 0x7b, 0x45, 0x69, 0x6f, 0x05, 0x2d, 0x77, 0xb4, + 0x57, 0x51, 0x04, 0xa9, 0xc3, 0x43, 0xb6, 0x0a, 0x1b, 0xdb, 0x7b, 0x26, 0xd8, 0xd9, 0x33, 0xc1, + 0xf7, 0x3d, 0x13, 0x6c, 0xed, 0x9b, 0x99, 0x9d, 0x7d, 0x33, 0xf3, 0x75, 0xdf, 0xcc, 0x3c, 0x5d, + 0xa8, 0xb9, 0xa2, 0x1e, 0x39, 0x56, 0x85, 0x79, 0x7f, 0x13, 0xc8, 0xcf, 0x0c, 0xaf, 0x6e, 0xda, + 0x2f, 0x6d, 0x12, 0x89, 0x7a, 0x6b, 0x4a, 0x11, 0x07, 0x94, 0x3b, 0x23, 0xf2, 0x09, 0xbe, 0xf9, + 0x27, 0x00, 0x00, 0xff, 0xff, 0x61, 0xa7, 0xa8, 0x78, 0x2e, 0x08, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // PubKeyHistory queries account pubkey history details based on address. + PubKeyHistory(ctx context.Context, in *QueryPubKeyHistoryRequest, opts ...grpc.CallOption) (*QueryPubKeyHistoryResponse, error) + // PubKeyHistoricalEntry queries account pubkey historical entry based on address and time. + PubKeyHistoricalEntry(ctx context.Context, in *QueryPubKeyHistoricalEntryRequest, opts ...grpc.CallOption) (*QueryPubKeyHistoricalEntryResponse, error) + // LastPubKeyHistoricalEntry queries account's last pubkey historical entry based on address. + LastPubKeyHistoricalEntry(ctx context.Context, in *QueryLastPubKeyHistoricalEntryRequest, opts ...grpc.CallOption) (*QueryLastPubKeyHistoricalEntryResponse, error) + // CurrentPubKeyEntry queries account's current pubkey entry based on address. + CurrentPubKeyEntry(ctx context.Context, in *QueryCurrentPubKeyEntryRequest, opts ...grpc.CallOption) (*QueryCurrentPubKeyEntryResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) PubKeyHistory(ctx context.Context, in *QueryPubKeyHistoryRequest, opts ...grpc.CallOption) (*QueryPubKeyHistoryResponse, error) { + out := new(QueryPubKeyHistoryResponse) + err := c.cc.Invoke(ctx, "/cosmos.changepubkey.v1beta1.Query/PubKeyHistory", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) PubKeyHistoricalEntry(ctx context.Context, in *QueryPubKeyHistoricalEntryRequest, opts ...grpc.CallOption) (*QueryPubKeyHistoricalEntryResponse, error) { + out := new(QueryPubKeyHistoricalEntryResponse) + err := c.cc.Invoke(ctx, "/cosmos.changepubkey.v1beta1.Query/PubKeyHistoricalEntry", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) LastPubKeyHistoricalEntry(ctx context.Context, in *QueryLastPubKeyHistoricalEntryRequest, opts ...grpc.CallOption) (*QueryLastPubKeyHistoricalEntryResponse, error) { + out := new(QueryLastPubKeyHistoricalEntryResponse) + err := c.cc.Invoke(ctx, "/cosmos.changepubkey.v1beta1.Query/LastPubKeyHistoricalEntry", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) CurrentPubKeyEntry(ctx context.Context, in *QueryCurrentPubKeyEntryRequest, opts ...grpc.CallOption) (*QueryCurrentPubKeyEntryResponse, error) { + out := new(QueryCurrentPubKeyEntryResponse) + err := c.cc.Invoke(ctx, "/cosmos.changepubkey.v1beta1.Query/CurrentPubKeyEntry", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // PubKeyHistory queries account pubkey history details based on address. + PubKeyHistory(context.Context, *QueryPubKeyHistoryRequest) (*QueryPubKeyHistoryResponse, error) + // PubKeyHistoricalEntry queries account pubkey historical entry based on address and time. + PubKeyHistoricalEntry(context.Context, *QueryPubKeyHistoricalEntryRequest) (*QueryPubKeyHistoricalEntryResponse, error) + // LastPubKeyHistoricalEntry queries account's last pubkey historical entry based on address. + LastPubKeyHistoricalEntry(context.Context, *QueryLastPubKeyHistoricalEntryRequest) (*QueryLastPubKeyHistoricalEntryResponse, error) + // CurrentPubKeyEntry queries account's current pubkey entry based on address. + CurrentPubKeyEntry(context.Context, *QueryCurrentPubKeyEntryRequest) (*QueryCurrentPubKeyEntryResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) PubKeyHistory(ctx context.Context, req *QueryPubKeyHistoryRequest) (*QueryPubKeyHistoryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PubKeyHistory not implemented") +} +func (*UnimplementedQueryServer) PubKeyHistoricalEntry(ctx context.Context, req *QueryPubKeyHistoricalEntryRequest) (*QueryPubKeyHistoricalEntryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PubKeyHistoricalEntry not implemented") +} +func (*UnimplementedQueryServer) LastPubKeyHistoricalEntry(ctx context.Context, req *QueryLastPubKeyHistoricalEntryRequest) (*QueryLastPubKeyHistoricalEntryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LastPubKeyHistoricalEntry not implemented") +} +func (*UnimplementedQueryServer) CurrentPubKeyEntry(ctx context.Context, req *QueryCurrentPubKeyEntryRequest) (*QueryCurrentPubKeyEntryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CurrentPubKeyEntry not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_PubKeyHistory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryPubKeyHistoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).PubKeyHistory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.changepubkey.v1beta1.Query/PubKeyHistory", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).PubKeyHistory(ctx, req.(*QueryPubKeyHistoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_PubKeyHistoricalEntry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryPubKeyHistoricalEntryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).PubKeyHistoricalEntry(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.changepubkey.v1beta1.Query/PubKeyHistoricalEntry", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).PubKeyHistoricalEntry(ctx, req.(*QueryPubKeyHistoricalEntryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_LastPubKeyHistoricalEntry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryLastPubKeyHistoricalEntryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).LastPubKeyHistoricalEntry(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.changepubkey.v1beta1.Query/LastPubKeyHistoricalEntry", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).LastPubKeyHistoricalEntry(ctx, req.(*QueryLastPubKeyHistoricalEntryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_CurrentPubKeyEntry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryCurrentPubKeyEntryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).CurrentPubKeyEntry(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.changepubkey.v1beta1.Query/CurrentPubKeyEntry", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).CurrentPubKeyEntry(ctx, req.(*QueryCurrentPubKeyEntryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "cosmos.changepubkey.v1beta1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PubKeyHistory", + Handler: _Query_PubKeyHistory_Handler, + }, + { + MethodName: "PubKeyHistoricalEntry", + Handler: _Query_PubKeyHistoricalEntry_Handler, + }, + { + MethodName: "LastPubKeyHistoricalEntry", + Handler: _Query_LastPubKeyHistoricalEntry_Handler, + }, + { + MethodName: "CurrentPubKeyEntry", + Handler: _Query_CurrentPubKeyEntry_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/changepubkey/v1beta1/pubkey_history.proto", +} + +func (m *PubKeyHistory) 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 *PubKeyHistory) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PubKeyHistory) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.EndTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintPubkeyHistory(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x1a + n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime):]) + if err2 != nil { + return 0, err2 + } + i -= n2 + i = encodeVarintPubkeyHistory(dAtA, i, uint64(n2)) + i-- + dAtA[i] = 0x12 + if len(m.PubKey) > 0 { + i -= len(m.PubKey) + copy(dAtA[i:], m.PubKey) + i = encodeVarintPubkeyHistory(dAtA, i, uint64(len(m.PubKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryPubKeyHistoryRequest) 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 *QueryPubKeyHistoryRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPubKeyHistoryRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintPubkeyHistory(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryPubKeyHistoryResponse) 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 *QueryPubKeyHistoryResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPubKeyHistoryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.History) > 0 { + for iNdEx := len(m.History) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.History[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPubkeyHistory(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryPubKeyHistoricalEntryRequest) 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 *QueryPubKeyHistoricalEntryRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPubKeyHistoricalEntryRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n3, err3 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) + if err3 != nil { + return 0, err3 + } + i -= n3 + i = encodeVarintPubkeyHistory(dAtA, i, uint64(n3)) + i-- + dAtA[i] = 0x12 + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintPubkeyHistory(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryPubKeyHistoricalEntryResponse) 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 *QueryPubKeyHistoricalEntryResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPubKeyHistoricalEntryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Entry.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPubkeyHistory(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryLastPubKeyHistoricalEntryRequest) 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 *QueryLastPubKeyHistoricalEntryRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryLastPubKeyHistoricalEntryRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintPubkeyHistory(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryLastPubKeyHistoricalEntryResponse) 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 *QueryLastPubKeyHistoricalEntryResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryLastPubKeyHistoricalEntryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Entry.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPubkeyHistory(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryCurrentPubKeyEntryRequest) 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 *QueryCurrentPubKeyEntryRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryCurrentPubKeyEntryRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintPubkeyHistory(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryCurrentPubKeyEntryResponse) 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 *QueryCurrentPubKeyEntryResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryCurrentPubKeyEntryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Entry.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPubkeyHistory(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintPubkeyHistory(dAtA []byte, offset int, v uint64) int { + offset -= sovPubkeyHistory(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *PubKeyHistory) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PubKey) + if l > 0 { + n += 1 + l + sovPubkeyHistory(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.StartTime) + n += 1 + l + sovPubkeyHistory(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.EndTime) + n += 1 + l + sovPubkeyHistory(uint64(l)) + return n +} + +func (m *QueryPubKeyHistoryRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovPubkeyHistory(uint64(l)) + } + return n +} + +func (m *QueryPubKeyHistoryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.History) > 0 { + for _, e := range m.History { + l = e.Size() + n += 1 + l + sovPubkeyHistory(uint64(l)) + } + } + return n +} + +func (m *QueryPubKeyHistoricalEntryRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovPubkeyHistory(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Time) + n += 1 + l + sovPubkeyHistory(uint64(l)) + return n +} + +func (m *QueryPubKeyHistoricalEntryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Entry.Size() + n += 1 + l + sovPubkeyHistory(uint64(l)) + return n +} + +func (m *QueryLastPubKeyHistoricalEntryRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovPubkeyHistory(uint64(l)) + } + return n +} + +func (m *QueryLastPubKeyHistoricalEntryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Entry.Size() + n += 1 + l + sovPubkeyHistory(uint64(l)) + return n +} + +func (m *QueryCurrentPubKeyEntryRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovPubkeyHistory(uint64(l)) + } + return n +} + +func (m *QueryCurrentPubKeyEntryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Entry.Size() + n += 1 + l + sovPubkeyHistory(uint64(l)) + return n +} + +func sovPubkeyHistory(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozPubkeyHistory(x uint64) (n int) { + return sovPubkeyHistory(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PubKeyHistory) 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 ErrIntOverflowPubkeyHistory + } + 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: PubKeyHistory: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PubKeyHistory: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PubKey = append(m.PubKey[:0], dAtA[iNdEx:postIndex]...) + if m.PubKey == nil { + m.PubKey = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.StartTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EndTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.EndTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPubkeyHistory(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryPubKeyHistoryRequest) 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 ErrIntOverflowPubkeyHistory + } + 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: QueryPubKeyHistoryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPubKeyHistoryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + 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 ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPubkeyHistory(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryPubKeyHistoryResponse) 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 ErrIntOverflowPubkeyHistory + } + 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: QueryPubKeyHistoryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPubKeyHistoryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field History", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.History = append(m.History, PubKeyHistory{}) + if err := m.History[len(m.History)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPubkeyHistory(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryPubKeyHistoricalEntryRequest) 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 ErrIntOverflowPubkeyHistory + } + 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: QueryPubKeyHistoricalEntryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPubKeyHistoricalEntryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + 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 ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPubkeyHistory(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryPubKeyHistoricalEntryResponse) 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 ErrIntOverflowPubkeyHistory + } + 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: QueryPubKeyHistoricalEntryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPubKeyHistoricalEntryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entry", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Entry.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPubkeyHistory(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryLastPubKeyHistoricalEntryRequest) 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 ErrIntOverflowPubkeyHistory + } + 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: QueryLastPubKeyHistoricalEntryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryLastPubKeyHistoricalEntryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + 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 ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPubkeyHistory(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryLastPubKeyHistoricalEntryResponse) 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 ErrIntOverflowPubkeyHistory + } + 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: QueryLastPubKeyHistoricalEntryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryLastPubKeyHistoricalEntryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entry", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Entry.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPubkeyHistory(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryCurrentPubKeyEntryRequest) 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 ErrIntOverflowPubkeyHistory + } + 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: QueryCurrentPubKeyEntryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryCurrentPubKeyEntryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + 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 ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPubkeyHistory(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryCurrentPubKeyEntryResponse) 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 ErrIntOverflowPubkeyHistory + } + 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: QueryCurrentPubKeyEntryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryCurrentPubKeyEntryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entry", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPubkeyHistory + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPubkeyHistory + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Entry.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPubkeyHistory(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPubkeyHistory + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPubkeyHistory(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPubkeyHistory + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthPubkeyHistory + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupPubkeyHistory + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthPubkeyHistory + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthPubkeyHistory = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPubkeyHistory = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupPubkeyHistory = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/auth/changepubkey/types/pubkey_history.pb.gw.go b/x/auth/changepubkey/types/pubkey_history.pb.gw.go new file mode 100644 index 000000000000..d4aa811da891 --- /dev/null +++ b/x/auth/changepubkey/types/pubkey_history.pb.gw.go @@ -0,0 +1,380 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: cosmos/changepubkey/v1beta1/pubkey_history.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage + +func request_Query_PubKeyHistory_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPubKeyHistoryRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := client.PubKeyHistory(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_PubKeyHistory_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPubKeyHistoryRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := server.PubKeyHistory(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_LastPubKeyHistoricalEntry_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryLastPubKeyHistoricalEntryRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := client.LastPubKeyHistoricalEntry(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_LastPubKeyHistoricalEntry_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryLastPubKeyHistoricalEntryRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := server.LastPubKeyHistoricalEntry(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_CurrentPubKeyEntry_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryCurrentPubKeyEntryRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := client.CurrentPubKeyEntry(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_CurrentPubKeyEntry_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryCurrentPubKeyEntryRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := server.CurrentPubKeyEntry(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_PubKeyHistory_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_PubKeyHistory_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_PubKeyHistory_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_LastPubKeyHistoricalEntry_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_LastPubKeyHistoricalEntry_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_LastPubKeyHistoricalEntry_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_CurrentPubKeyEntry_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_CurrentPubKeyEntry_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_CurrentPubKeyEntry_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_PubKeyHistory_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_PubKeyHistory_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_PubKeyHistory_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_LastPubKeyHistoricalEntry_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_LastPubKeyHistoricalEntry_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_LastPubKeyHistoricalEntry_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_CurrentPubKeyEntry_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_CurrentPubKeyEntry_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_CurrentPubKeyEntry_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_PubKeyHistory_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "changepubkey", "v1beta1", "pubkey_history", "address"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_LastPubKeyHistoricalEntry_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "changepubkey", "v1beta1", "last_pubkey_historical_entry", "address"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_CurrentPubKeyEntry_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "changepubkey", "v1beta1", "current_pubkey_entry", "address"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_Query_PubKeyHistory_0 = runtime.ForwardResponseMessage + + forward_Query_LastPubKeyHistoricalEntry_0 = runtime.ForwardResponseMessage + + forward_Query_CurrentPubKeyEntry_0 = runtime.ForwardResponseMessage +) diff --git a/x/auth/changepubkey/types/test_common.go b/x/auth/changepubkey/types/test_common.go new file mode 100644 index 000000000000..347faba046a9 --- /dev/null +++ b/x/auth/changepubkey/types/test_common.go @@ -0,0 +1,30 @@ +package types + +import ( + "github.com/tendermint/tendermint/crypto" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// NewTestMsg generates a test message +func NewTestMsg(addrs ...sdk.AccAddress) *testdata.TestMsg { + return testdata.NewTestMsg(addrs...) +} + +// NewTestCoins coins to more than cover the fee +func NewTestCoins() sdk.Coins { + return sdk.Coins{ + sdk.NewInt64Coin("atom", 10000000), + } +} + +// KeyTestPubAddr generates a test key pair +func KeyTestPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) { + key := secp256k1.GenPrivKey() + pub := key.PubKey() + addr := sdk.AccAddress(pub.Address()) + return key, pub, addr +} diff --git a/x/auth/changepubkey/types/tx.pb.go b/x/auth/changepubkey/types/tx.pb.go new file mode 100644 index 000000000000..6b1aef215d2d --- /dev/null +++ b/x/auth/changepubkey/types/tx.pb.go @@ -0,0 +1,591 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/changepubkey/v1beta1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// MsgChangePubKey defines a message that enables changing a pubkey +// of an account. +type MsgChangePubKey struct { + Address github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=address,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"address,omitempty"` + PubKey []byte `protobuf:"bytes,2,opt,name=pub_key,json=pubKey,proto3" json:"public_key,omitempty" yaml:"public_key"` +} + +func (m *MsgChangePubKey) Reset() { *m = MsgChangePubKey{} } +func (m *MsgChangePubKey) String() string { return proto.CompactTextString(m) } +func (*MsgChangePubKey) ProtoMessage() {} +func (*MsgChangePubKey) Descriptor() ([]byte, []int) { + return fileDescriptor_0c6e8f4793cfde65, []int{0} +} +func (m *MsgChangePubKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChangePubKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChangePubKey.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 *MsgChangePubKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChangePubKey.Merge(m, src) +} +func (m *MsgChangePubKey) XXX_Size() int { + return m.Size() +} +func (m *MsgChangePubKey) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChangePubKey.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgChangePubKey proto.InternalMessageInfo + +func (m *MsgChangePubKey) GetAddress() github_com_cosmos_cosmos_sdk_types.AccAddress { + if m != nil { + return m.Address + } + return nil +} + +// MsgChangePubKeyResponse defines the Msg/ChangePubKey response type. +type MsgChangePubKeyResponse struct { +} + +func (m *MsgChangePubKeyResponse) Reset() { *m = MsgChangePubKeyResponse{} } +func (m *MsgChangePubKeyResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChangePubKeyResponse) ProtoMessage() {} +func (*MsgChangePubKeyResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_0c6e8f4793cfde65, []int{1} +} +func (m *MsgChangePubKeyResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChangePubKeyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChangePubKeyResponse.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 *MsgChangePubKeyResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChangePubKeyResponse.Merge(m, src) +} +func (m *MsgChangePubKeyResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgChangePubKeyResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChangePubKeyResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgChangePubKeyResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgChangePubKey)(nil), "cosmos.changepubkey.v1beta1.MsgChangePubKey") + proto.RegisterType((*MsgChangePubKeyResponse)(nil), "cosmos.changepubkey.v1beta1.MsgChangePubKeyResponse") +} + +func init() { + proto.RegisterFile("cosmos/changepubkey/v1beta1/tx.proto", fileDescriptor_0c6e8f4793cfde65) +} + +var fileDescriptor_0c6e8f4793cfde65 = []byte{ + // 307 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x49, 0xce, 0x2f, 0xce, + 0xcd, 0x2f, 0xd6, 0x4f, 0xce, 0x48, 0xcc, 0x4b, 0x4f, 0x2d, 0x28, 0x4d, 0xca, 0x4e, 0xad, 0xd4, + 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, + 0x17, 0x92, 0x86, 0xa8, 0xd2, 0x43, 0x56, 0xa5, 0x07, 0x55, 0x25, 0x25, 0x92, 0x9e, 0x9f, 0x9e, + 0x0f, 0x56, 0xa7, 0x0f, 0x62, 0x41, 0xb4, 0x28, 0x2d, 0x63, 0xe4, 0xe2, 0xf7, 0x2d, 0x4e, 0x77, + 0x06, 0xeb, 0x08, 0x28, 0x4d, 0xf2, 0x4e, 0xad, 0x14, 0xf2, 0xe6, 0x62, 0x4f, 0x4c, 0x49, 0x29, + 0x4a, 0x2d, 0x2e, 0x96, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x71, 0x32, 0xfc, 0x75, 0x4f, 0x5e, 0x37, + 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xe6, 0x18, 0x30, 0xa5, 0x5b, + 0x9c, 0x92, 0xad, 0x5f, 0x52, 0x59, 0x90, 0x5a, 0xac, 0xe7, 0x98, 0x9c, 0xec, 0x08, 0xd1, 0x18, + 0x04, 0x33, 0x41, 0xc8, 0x8d, 0x8b, 0xbd, 0xa0, 0x34, 0x29, 0x3e, 0x3b, 0xb5, 0x52, 0x82, 0x09, + 0x6c, 0x98, 0xee, 0xab, 0x7b, 0xf2, 0x22, 0x05, 0xa5, 0x49, 0x39, 0x99, 0xc9, 0x20, 0x51, 0x9d, + 0xfc, 0xdc, 0xcc, 0x92, 0xd4, 0xdc, 0x82, 0x92, 0xca, 0x4f, 0xf7, 0xe4, 0x05, 0x2b, 0x13, 0x73, + 0x73, 0xac, 0x94, 0x10, 0xb2, 0x4a, 0x41, 0x6c, 0x05, 0x60, 0x47, 0x29, 0x49, 0x72, 0x89, 0xa3, + 0xb9, 0x33, 0x28, 0xb5, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0xd5, 0xa8, 0x92, 0x8b, 0xd9, 0xb7, 0x38, + 0x5d, 0xa8, 0x88, 0x8b, 0x07, 0xc5, 0x1b, 0x3a, 0x7a, 0x78, 0x82, 0x43, 0x0f, 0xcd, 0x30, 0x29, + 0x13, 0x52, 0x54, 0xc3, 0xac, 0x76, 0x0a, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, + 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, + 0x86, 0x28, 0x33, 0xbc, 0xe1, 0x55, 0xa1, 0x9f, 0x58, 0x5a, 0x92, 0x81, 0x1a, 0x9d, 0xe0, 0x30, + 0x4c, 0x62, 0x03, 0xc7, 0x8b, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xb8, 0xf4, 0x31, 0x6b, 0xf2, + 0x01, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // ChangePubKey defines a method for changing a pubkey of an account + ChangePubKey(ctx context.Context, in *MsgChangePubKey, opts ...grpc.CallOption) (*MsgChangePubKeyResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) ChangePubKey(ctx context.Context, in *MsgChangePubKey, opts ...grpc.CallOption) (*MsgChangePubKeyResponse, error) { + out := new(MsgChangePubKeyResponse) + err := c.cc.Invoke(ctx, "/cosmos.changepubkey.v1beta1.Msg/ChangePubKey", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // ChangePubKey defines a method for changing a pubkey of an account + ChangePubKey(context.Context, *MsgChangePubKey) (*MsgChangePubKeyResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) ChangePubKey(ctx context.Context, req *MsgChangePubKey) (*MsgChangePubKeyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChangePubKey not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_ChangePubKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChangePubKey) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ChangePubKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.changepubkey.v1beta1.Msg/ChangePubKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChangePubKey(ctx, req.(*MsgChangePubKey)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "cosmos.changepubkey.v1beta1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ChangePubKey", + Handler: _Msg_ChangePubKey_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/changepubkey/v1beta1/tx.proto", +} + +func (m *MsgChangePubKey) 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 *MsgChangePubKey) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChangePubKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PubKey) > 0 { + i -= len(m.PubKey) + copy(dAtA[i:], m.PubKey) + i = encodeVarintTx(dAtA, i, uint64(len(m.PubKey))) + i-- + dAtA[i] = 0x12 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintTx(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgChangePubKeyResponse) 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 *MsgChangePubKeyResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChangePubKeyResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgChangePubKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.PubKey) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChangePubKeyResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgChangePubKey) 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 ErrIntOverflowTx + } + 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: MsgChangePubKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChangePubKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = append(m.Address[:0], dAtA[iNdEx:postIndex]...) + if m.Address == nil { + m.Address = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PubKey = append(m.PubKey[:0], dAtA[iNdEx:postIndex]...) + if m.PubKey == nil { + m.PubKey = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgChangePubKeyResponse) 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 ErrIntOverflowTx + } + 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: MsgChangePubKeyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgChangePubKeyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/auth/legacy/v040/migrate_test.go b/x/auth/legacy/v040/migrate_test.go index e24104609547..59fad2403a62 100644 --- a/x/auth/legacy/v040/migrate_test.go +++ b/x/auth/legacy/v040/migrate_test.go @@ -233,7 +233,9 @@ func TestMigrate(t *testing.T) { } ], "params": { + "enable_change_pubkey": false, "max_memo_characters": "10", + "pubkey_change_cost": "0", "sig_verify_cost_ed25519": "40", "sig_verify_cost_secp256k1": "50", "tx_sig_limit": "20", diff --git a/x/auth/simulation/genesis.go b/x/auth/simulation/genesis.go index 2da36b54fa82..8f49b258cbc6 100644 --- a/x/auth/simulation/genesis.go +++ b/x/auth/simulation/genesis.go @@ -19,6 +19,8 @@ const ( TxSizeCostPerByte = "tx_size_cost_per_byte" SigVerifyCostED25519 = "sig_verify_cost_ed25519" SigVerifyCostSECP256K1 = "sig_verify_cost_secp256k1" + PubKeyChangeCost = "pubkey_change_cost" + EnableChangePubKey = "enable_change_pubkey" ) // RandomGenesisAccounts defines the default RandomGenesisAccountsFn used on the SDK. @@ -87,6 +89,16 @@ func GenSigVerifyCostSECP256K1(r *rand.Rand) uint64 { return uint64(simulation.RandIntBetween(r, 500, 1000)) } +// GenPubKeyChangeCost randomized PubKeyChangeCost +func GenPubKeyChangeCost(r *rand.Rand) uint64 { + return uint64(simulation.RandIntBetween(r, 2500, 5000)) +} + +// GenEnableChangePubKey randomized EnableChangePubKey +func GenEnableChangePubKey(r *rand.Rand) bool { + return true +} + // RandomizedGenState generates a random GenesisState for auth func RandomizedGenState(simState *module.SimulationState, randGenAccountsFn types.RandomGenesisAccountsFn) { var maxMemoChars uint64 @@ -119,8 +131,20 @@ func RandomizedGenState(simState *module.SimulationState, randGenAccountsFn type func(r *rand.Rand) { sigVerifyCostSECP256K1 = GenSigVerifyCostSECP256K1(r) }, ) + var pubKeyChangeCost uint64 + simState.AppParams.GetOrGenerate( + simState.Cdc, PubKeyChangeCost, &pubKeyChangeCost, simState.Rand, + func(r *rand.Rand) { pubKeyChangeCost = GenPubKeyChangeCost(r) }, + ) + + var enableChangePubKey bool + simState.AppParams.GetOrGenerate( + simState.Cdc, EnableChangePubKey, &enableChangePubKey, simState.Rand, + func(r *rand.Rand) { enableChangePubKey = GenEnableChangePubKey(r) }, + ) + params := types.NewParams(maxMemoChars, txSigLimit, txSizeCostPerByte, - sigVerifyCostED25519, sigVerifyCostSECP256K1) + sigVerifyCostED25519, sigVerifyCostSECP256K1, pubKeyChangeCost, enableChangePubKey) genesisAccs := randGenAccountsFn(simState) authGenesis := types.NewGenesisState(params, genesisAccs) diff --git a/x/auth/simulation/genesis_test.go b/x/auth/simulation/genesis_test.go index 830a264ff4c6..a97ed0249ed8 100644 --- a/x/auth/simulation/genesis_test.go +++ b/x/auth/simulation/genesis_test.go @@ -43,6 +43,8 @@ func TestRandomizedGenState(t *testing.T) { require.Equal(t, uint64(0x8c), authGenesis.Params.GetMaxMemoCharacters()) require.Equal(t, uint64(0x2b6), authGenesis.Params.GetSigVerifyCostED25519()) require.Equal(t, uint64(0x1ff), authGenesis.Params.GetSigVerifyCostSecp256k1()) + require.Equal(t, uint64(0xc5a), authGenesis.Params.GetPubKeyChangeCost()) + require.Equal(t, true, authGenesis.Params.GetEnableChangePubKey()) require.Equal(t, uint64(9), authGenesis.Params.GetTxSigLimit()) require.Equal(t, uint64(5), authGenesis.Params.GetTxSizeCostPerByte()) diff --git a/x/auth/spec/07_params.md b/x/auth/spec/07_params.md index 93ddc89c2219..3e4097ed7633 100644 --- a/x/auth/spec/07_params.md +++ b/x/auth/spec/07_params.md @@ -13,3 +13,5 @@ The auth module contains the following parameters: | TxSizeCostPerByte | string (uint64) | "10" | | SigVerifyCostED25519 | string (uint64) | "590" | | SigVerifyCostSecp256k1 | string (uint64) | "1000" | +| PubKeyChangeCost | string (uint64) | "5000" | +| EnableChangePubKey | string (bool) | "true" | \ No newline at end of file diff --git a/x/auth/types/auth.pb.go b/x/auth/types/auth.pb.go index 4a05cf8158e7..f01ebc7492bb 100644 --- a/x/auth/types/auth.pb.go +++ b/x/auth/types/auth.pb.go @@ -113,6 +113,8 @@ type Params struct { TxSizeCostPerByte uint64 `protobuf:"varint,3,opt,name=tx_size_cost_per_byte,json=txSizeCostPerByte,proto3" json:"tx_size_cost_per_byte,omitempty" yaml:"tx_size_cost_per_byte"` SigVerifyCostED25519 uint64 `protobuf:"varint,4,opt,name=sig_verify_cost_ed25519,json=sigVerifyCostEd25519,proto3" json:"sig_verify_cost_ed25519,omitempty" yaml:"sig_verify_cost_ed25519"` SigVerifyCostSecp256k1 uint64 `protobuf:"varint,5,opt,name=sig_verify_cost_secp256k1,json=sigVerifyCostSecp256k1,proto3" json:"sig_verify_cost_secp256k1,omitempty" yaml:"sig_verify_cost_secp256k1"` + PubKeyChangeCost uint64 `protobuf:"varint,6,opt,name=pubkey_change_cost,json=pubkeyChangeCost,proto3" json:"pubkey_change_cost,omitempty" yaml:"pubkey_change_cost"` + EnableChangePubKey bool `protobuf:"varint,7,opt,name=enable_change_pubkey,json=enableChangePubkey,proto3" json:"enable_change_pubkey,omitempty" yaml:"enable_change_pubkey"` } func (m *Params) Reset() { *m = Params{} } @@ -182,6 +184,20 @@ func (m *Params) GetSigVerifyCostSecp256k1() uint64 { return 0 } +func (m *Params) GetPubKeyChangeCost() uint64 { + if m != nil { + return m.PubKeyChangeCost + } + return 0 +} + +func (m *Params) GetEnableChangePubKey() bool { + if m != nil { + return m.EnableChangePubKey + } + return false +} + func init() { proto.RegisterType((*BaseAccount)(nil), "cosmos.auth.v1beta1.BaseAccount") proto.RegisterType((*ModuleAccount)(nil), "cosmos.auth.v1beta1.ModuleAccount") @@ -191,50 +207,55 @@ func init() { func init() { proto.RegisterFile("cosmos/auth/v1beta1/auth.proto", fileDescriptor_7e1f7e915d020d2d) } var fileDescriptor_7e1f7e915d020d2d = []byte{ - // 674 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0x4d, 0x4f, 0xdb, 0x4a, - 0x14, 0x8d, 0x5f, 0xf2, 0xf8, 0x98, 0x00, 0x12, 0x26, 0x80, 0x93, 0xf7, 0x64, 0x5b, 0x5e, 0xe5, - 0x49, 0x2f, 0x8e, 0x92, 0x8a, 0x4a, 0x64, 0x51, 0x15, 0xd3, 0x2e, 0x50, 0x0b, 0x42, 0x46, 0xea, - 0xa2, 0xaa, 0xe4, 0x8e, 0x9d, 0xc1, 0x58, 0x64, 0x32, 0xc6, 0x33, 0x46, 0x31, 0xbf, 0xa0, 0xcb, - 0x2e, 0xbb, 0xe4, 0x47, 0xf0, 0x0f, 0xba, 0xe9, 0x12, 0xb1, 0xea, 0xca, 0xad, 0xc2, 0xa6, 0xea, - 0x32, 0xfb, 0x4a, 0x95, 0x67, 0x9c, 0x90, 0xa0, 0x74, 0x95, 0xb9, 0xe7, 0x9c, 0x7b, 0xee, 0x9d, - 0x7b, 0xe3, 0x01, 0xaa, 0x47, 0x28, 0x26, 0xb4, 0x09, 0x63, 0x76, 0xd6, 0xbc, 0x6c, 0xb9, 0x88, - 0xc1, 0x16, 0x0f, 0xcc, 0x30, 0x22, 0x8c, 0xc8, 0x1b, 0x82, 0x37, 0x39, 0x94, 0xf3, 0xb5, 0xaa, - 0x00, 0x1d, 0x2e, 0x69, 0xe6, 0x0a, 0x1e, 0xd4, 0x2a, 0x3e, 0xf1, 0x89, 0xc0, 0xb3, 0x53, 0x8e, - 0x56, 0x7d, 0x42, 0xfc, 0x1e, 0x6a, 0xf2, 0xc8, 0x8d, 0x4f, 0x9b, 0xb0, 0x9f, 0x08, 0xca, 0xf8, - 0x25, 0x81, 0xb2, 0x05, 0x29, 0xda, 0xf3, 0x3c, 0x12, 0xf7, 0x99, 0xac, 0x80, 0x45, 0xd8, 0xed, - 0x46, 0x88, 0x52, 0x45, 0xd2, 0xa5, 0xfa, 0xb2, 0x3d, 0x0e, 0xe5, 0x77, 0x60, 0x31, 0x8c, 0x5d, - 0xe7, 0x1c, 0x25, 0xca, 0x5f, 0xba, 0x54, 0x2f, 0xb7, 0x2b, 0xa6, 0xb0, 0x35, 0xc7, 0xb6, 0xe6, - 0x5e, 0x3f, 0xb1, 0x1a, 0x3f, 0x53, 0xad, 0x12, 0xc6, 0x6e, 0x2f, 0xf0, 0x32, 0xed, 0xff, 0x04, - 0x07, 0x0c, 0xe1, 0x90, 0x25, 0xa3, 0x54, 0x5b, 0x4f, 0x20, 0xee, 0x75, 0x8c, 0x07, 0xd6, 0xb0, - 0x17, 0xc2, 0xd8, 0x7d, 0x85, 0x12, 0xf9, 0x39, 0x58, 0x83, 0xa2, 0x05, 0xa7, 0x1f, 0x63, 0x17, - 0x45, 0x4a, 0x51, 0x97, 0xea, 0x25, 0xab, 0x3a, 0x4a, 0xb5, 0x4d, 0x91, 0x36, 0xcb, 0x1b, 0xf6, - 0x6a, 0x0e, 0x1c, 0xf1, 0x58, 0xae, 0x81, 0x25, 0x8a, 0x2e, 0x62, 0xd4, 0xf7, 0x90, 0x52, 0xca, - 0x72, 0xed, 0x49, 0xdc, 0x51, 0x3e, 0x5c, 0x6b, 0x85, 0x4f, 0xd7, 0x5a, 0xe1, 0xc7, 0xb5, 0x56, - 0xb8, 0xbb, 0x69, 0x2c, 0xe5, 0xd7, 0x3d, 0x30, 0x3e, 0x4b, 0x60, 0xf5, 0x90, 0x74, 0xe3, 0xde, - 0x64, 0x02, 0xef, 0xc1, 0x8a, 0x0b, 0x29, 0x72, 0x72, 0x77, 0x3e, 0x86, 0x72, 0x5b, 0x37, 0xe7, - 0x6c, 0xc2, 0x9c, 0x9a, 0x9c, 0xf5, 0xcf, 0x6d, 0xaa, 0x49, 0xa3, 0x54, 0xdb, 0x10, 0xdd, 0x4e, - 0x7b, 0x18, 0x76, 0xd9, 0x9d, 0x9a, 0xb1, 0x0c, 0x4a, 0x7d, 0x88, 0x11, 0x1f, 0xe3, 0xb2, 0xcd, - 0xcf, 0xb2, 0x0e, 0xca, 0x21, 0x8a, 0x70, 0x40, 0x69, 0x40, 0xfa, 0x54, 0x29, 0xea, 0xc5, 0xfa, - 0xb2, 0x3d, 0x0d, 0x75, 0x6a, 0xe3, 0x3b, 0xdc, 0xdd, 0x34, 0xd6, 0x66, 0x5a, 0x3e, 0x30, 0xbe, - 0x15, 0xc1, 0xc2, 0x31, 0x8c, 0x20, 0xa6, 0xf2, 0x11, 0xd8, 0xc0, 0x70, 0xe0, 0x60, 0x84, 0x89, - 0xe3, 0x9d, 0xc1, 0x08, 0x7a, 0x0c, 0x45, 0x62, 0x99, 0x25, 0x4b, 0x1d, 0xa5, 0x5a, 0x4d, 0xf4, - 0x37, 0x47, 0x64, 0xd8, 0xeb, 0x18, 0x0e, 0x0e, 0x11, 0x26, 0xfb, 0x13, 0x4c, 0xde, 0x05, 0x2b, - 0x6c, 0xe0, 0xd0, 0xc0, 0x77, 0x7a, 0x01, 0x0e, 0x18, 0x6f, 0xba, 0x64, 0x6d, 0x3f, 0x5c, 0x74, - 0x9a, 0x35, 0x6c, 0xc0, 0x06, 0x27, 0x81, 0xff, 0x3a, 0x0b, 0x64, 0x1b, 0x6c, 0x72, 0xf2, 0x0a, - 0x39, 0x1e, 0xa1, 0xcc, 0x09, 0x51, 0xe4, 0xb8, 0x09, 0x43, 0xf9, 0x6a, 0xf5, 0x51, 0xaa, 0xfd, - 0x3b, 0xe5, 0xf1, 0x58, 0x66, 0xd8, 0xeb, 0x99, 0xd9, 0x15, 0xda, 0x27, 0x94, 0x1d, 0xa3, 0xc8, - 0x4a, 0x18, 0x92, 0x2f, 0xc0, 0x76, 0x56, 0xed, 0x12, 0x45, 0xc1, 0x69, 0x22, 0xf4, 0xa8, 0xdb, - 0xde, 0xd9, 0x69, 0xed, 0x8a, 0xa5, 0x5b, 0x9d, 0x61, 0xaa, 0x55, 0x4e, 0x02, 0xff, 0x0d, 0x57, - 0x64, 0xa9, 0x2f, 0x5f, 0x70, 0x7e, 0x94, 0x6a, 0xaa, 0xa8, 0xf6, 0x07, 0x03, 0xc3, 0xae, 0xd0, - 0x99, 0x3c, 0x01, 0xcb, 0x09, 0xa8, 0x3e, 0xce, 0xa0, 0xc8, 0x0b, 0xdb, 0x3b, 0x4f, 0xcf, 0x5b, - 0xca, 0xdf, 0xbc, 0xe8, 0xb3, 0x61, 0xaa, 0x6d, 0xcd, 0x14, 0x3d, 0x19, 0x2b, 0x46, 0xa9, 0xa6, - 0xcf, 0x2f, 0x3b, 0x31, 0x31, 0xec, 0x2d, 0x3a, 0x37, 0xb7, 0xb3, 0x94, 0xff, 0x67, 0x25, 0x6b, - 0xff, 0xcb, 0x50, 0x95, 0x6e, 0x87, 0xaa, 0xf4, 0x7d, 0xa8, 0x4a, 0x1f, 0xef, 0xd5, 0xc2, 0xed, - 0xbd, 0x5a, 0xf8, 0x7a, 0xaf, 0x16, 0xde, 0xfe, 0xe7, 0x07, 0xec, 0x2c, 0x76, 0x4d, 0x8f, 0xe0, - 0xfc, 0x2d, 0xc8, 0x7f, 0x1a, 0xb4, 0x7b, 0xde, 0x1c, 0x88, 0xa7, 0x85, 0x25, 0x21, 0xa2, 0xee, - 0x02, 0xff, 0x52, 0x9f, 0xfc, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x49, 0x90, 0x16, 0xd9, 0x76, 0x04, - 0x00, 0x00, + // 757 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0x3f, 0x6f, 0xdb, 0x46, + 0x14, 0x17, 0x6b, 0xc5, 0x7f, 0x4e, 0x49, 0x10, 0x9f, 0x95, 0x84, 0x52, 0x0a, 0x1e, 0xc1, 0x49, + 0x05, 0x6a, 0x09, 0x72, 0xe1, 0x02, 0xd1, 0x50, 0x34, 0x54, 0x33, 0x04, 0x6d, 0x02, 0x83, 0x06, + 0x3a, 0x14, 0x05, 0xd8, 0x23, 0xf5, 0x42, 0x13, 0x12, 0x79, 0x0c, 0xef, 0x18, 0x88, 0xf9, 0x04, + 0x1d, 0x3b, 0x76, 0xf4, 0xda, 0x3d, 0xdf, 0xa0, 0x4b, 0x47, 0xc3, 0x53, 0x27, 0xa2, 0x90, 0x97, + 0xa2, 0x23, 0xf7, 0x02, 0x05, 0xef, 0x28, 0x59, 0x32, 0xd4, 0x89, 0x7c, 0xbf, 0x3f, 0xef, 0xbd, + 0x7b, 0x0f, 0x77, 0xc8, 0xf0, 0x19, 0x8f, 0x18, 0x1f, 0xd0, 0x4c, 0x5c, 0x0c, 0xde, 0x0f, 0x3d, + 0x10, 0x74, 0x28, 0x83, 0x7e, 0x92, 0x32, 0xc1, 0xf0, 0x91, 0xe2, 0xfb, 0x12, 0xaa, 0xf9, 0x6e, + 0x47, 0x81, 0xae, 0x94, 0x0c, 0x6a, 0x85, 0x0c, 0xba, 0xed, 0x80, 0x05, 0x4c, 0xe1, 0xd5, 0x5f, + 0x8d, 0x76, 0x02, 0xc6, 0x82, 0x19, 0x0c, 0x64, 0xe4, 0x65, 0x6f, 0x07, 0x34, 0xce, 0x15, 0x65, + 0xfd, 0xab, 0xa1, 0x96, 0x4d, 0x39, 0xbc, 0xf0, 0x7d, 0x96, 0xc5, 0x02, 0xeb, 0x68, 0x8f, 0x4e, + 0x26, 0x29, 0x70, 0xae, 0x6b, 0xa6, 0xd6, 0x3b, 0x70, 0x96, 0x21, 0xfe, 0x11, 0xed, 0x25, 0x99, + 0xe7, 0x4e, 0x21, 0xd7, 0x3f, 0x31, 0xb5, 0x5e, 0xeb, 0xa4, 0xdd, 0x57, 0x69, 0xfb, 0xcb, 0xb4, + 0xfd, 0x17, 0x71, 0x6e, 0x1f, 0xff, 0x53, 0x90, 0x76, 0x92, 0x79, 0xb3, 0xd0, 0xaf, 0xb4, 0x9f, + 0xb3, 0x28, 0x14, 0x10, 0x25, 0x22, 0x2f, 0x0b, 0x72, 0x98, 0xd3, 0x68, 0x36, 0xb2, 0x6e, 0x59, + 0xcb, 0xd9, 0x4d, 0x32, 0xef, 0x5b, 0xc8, 0xf1, 0xd7, 0xe8, 0x21, 0x55, 0x2d, 0xb8, 0x71, 0x16, + 0x79, 0x90, 0xea, 0x3b, 0xa6, 0xd6, 0x6b, 0xda, 0x9d, 0xb2, 0x20, 0x8f, 0x95, 0x6d, 0x93, 0xb7, + 0x9c, 0x07, 0x35, 0xf0, 0x46, 0xc6, 0xb8, 0x8b, 0xf6, 0x39, 0xbc, 0xcb, 0x20, 0xf6, 0x41, 0x6f, + 0x56, 0x5e, 0x67, 0x15, 0x8f, 0xf4, 0x9f, 0x2f, 0x49, 0xe3, 0xd7, 0x4b, 0xd2, 0xf8, 0xfb, 0x92, + 0x34, 0xae, 0x3f, 0x1e, 0xef, 0xd7, 0xc7, 0x7d, 0x65, 0xfd, 0xae, 0xa1, 0x07, 0xaf, 0xd9, 0x24, + 0x9b, 0xad, 0x26, 0xf0, 0x13, 0xba, 0xef, 0x51, 0x0e, 0x6e, 0x9d, 0x5d, 0x8e, 0xa1, 0x75, 0x62, + 0xf6, 0xb7, 0x6c, 0xa2, 0xbf, 0x36, 0x39, 0xfb, 0xd9, 0x55, 0x41, 0xb4, 0xb2, 0x20, 0x47, 0xaa, + 0xdb, 0xf5, 0x1c, 0x96, 0xd3, 0xf2, 0xd6, 0x66, 0x8c, 0x51, 0x33, 0xa6, 0x11, 0xc8, 0x31, 0x1e, + 0x38, 0xf2, 0x1f, 0x9b, 0xa8, 0x95, 0x40, 0x1a, 0x85, 0x9c, 0x87, 0x2c, 0xe6, 0xfa, 0x8e, 0xb9, + 0xd3, 0x3b, 0x70, 0xd6, 0xa1, 0x51, 0x77, 0x79, 0x86, 0xeb, 0x8f, 0xc7, 0x0f, 0x37, 0x5a, 0x7e, + 0x65, 0xfd, 0x76, 0x0f, 0xed, 0x9e, 0xd1, 0x94, 0x46, 0x1c, 0xbf, 0x41, 0x47, 0x11, 0x9d, 0xbb, + 0x11, 0x44, 0xcc, 0xf5, 0x2f, 0x68, 0x4a, 0x7d, 0x01, 0xa9, 0x5a, 0x66, 0xd3, 0x36, 0xca, 0x82, + 0x74, 0x55, 0x7f, 0x5b, 0x44, 0x96, 0x73, 0x18, 0xd1, 0xf9, 0x6b, 0x88, 0xd8, 0x78, 0x85, 0xe1, + 0xe7, 0xe8, 0xbe, 0x98, 0xbb, 0x3c, 0x0c, 0xdc, 0x59, 0x18, 0x85, 0x42, 0x36, 0xdd, 0xb4, 0x9f, + 0xde, 0x1e, 0x74, 0x9d, 0xb5, 0x1c, 0x24, 0xe6, 0xe7, 0x61, 0xf0, 0x5d, 0x15, 0x60, 0x07, 0x3d, + 0x96, 0xe4, 0x07, 0x70, 0x7d, 0xc6, 0x85, 0x9b, 0x40, 0xea, 0x7a, 0xb9, 0x80, 0x7a, 0xb5, 0x66, + 0x59, 0x90, 0x4f, 0xd7, 0x72, 0xdc, 0x95, 0x59, 0xce, 0x61, 0x95, 0xec, 0x03, 0x8c, 0x19, 0x17, + 0x67, 0x90, 0xda, 0xb9, 0x00, 0xfc, 0x0e, 0x3d, 0xad, 0xaa, 0xbd, 0x87, 0x34, 0x7c, 0x9b, 0x2b, + 0x3d, 0x4c, 0x4e, 0x4e, 0x4f, 0x87, 0xcf, 0xd5, 0xd2, 0xed, 0xd1, 0xa2, 0x20, 0xed, 0xf3, 0x30, + 0xf8, 0x5e, 0x2a, 0x2a, 0xeb, 0xcb, 0x6f, 0x24, 0x5f, 0x16, 0xc4, 0x50, 0xd5, 0xfe, 0x27, 0x81, + 0xe5, 0xb4, 0xf9, 0x86, 0x4f, 0xc1, 0x38, 0x47, 0x9d, 0xbb, 0x0e, 0x0e, 0x7e, 0x72, 0x72, 0xfa, + 0xe5, 0x74, 0xa8, 0xdf, 0x93, 0x45, 0xbf, 0x5a, 0x14, 0xe4, 0xc9, 0x46, 0xd1, 0xf3, 0xa5, 0xa2, + 0x2c, 0x88, 0xb9, 0xbd, 0xec, 0x2a, 0x89, 0xe5, 0x3c, 0xe1, 0x5b, 0xbd, 0xd8, 0x45, 0x38, 0xc9, + 0xbc, 0x29, 0xe4, 0xd5, 0x96, 0xe2, 0x40, 0x0d, 0x48, 0xdf, 0x95, 0x35, 0x87, 0x8b, 0x82, 0x3c, + 0x3a, 0x93, 0xb7, 0x67, 0x2c, 0xc9, 0xca, 0x5a, 0x16, 0xa4, 0xb3, 0xba, 0x64, 0x77, 0x7c, 0x96, + 0xf3, 0x48, 0x81, 0xb7, 0x72, 0x1c, 0xa0, 0x36, 0xc4, 0xd4, 0x9b, 0xc1, 0x52, 0xa8, 0x14, 0xfa, + 0x9e, 0xa9, 0xf5, 0xf6, 0xed, 0xd3, 0x45, 0x41, 0xf0, 0x4b, 0xc9, 0x2b, 0x8f, 0x2a, 0x57, 0x16, + 0xe4, 0x99, 0x2a, 0xb2, 0xcd, 0x6b, 0x39, 0x18, 0x36, 0x2d, 0x53, 0xc8, 0x47, 0xfb, 0xf5, 0xed, + 0xd3, 0xec, 0xf1, 0x1f, 0x0b, 0x43, 0xbb, 0x5a, 0x18, 0xda, 0x5f, 0x0b, 0x43, 0xfb, 0xe5, 0xc6, + 0x68, 0x5c, 0xdd, 0x18, 0x8d, 0x3f, 0x6f, 0x8c, 0xc6, 0x0f, 0x9f, 0x05, 0xa1, 0xb8, 0xc8, 0xbc, + 0xbe, 0xcf, 0xa2, 0xfa, 0x55, 0xab, 0x3f, 0xc7, 0x7c, 0x32, 0x1d, 0xcc, 0xd5, 0x23, 0x29, 0xf2, + 0x04, 0xb8, 0xb7, 0x2b, 0xdf, 0x9c, 0x2f, 0xfe, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x93, 0xf3, + 0xb0, 0x40, 0x05, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -271,6 +292,12 @@ func (this *Params) Equal(that interface{}) bool { if this.SigVerifyCostSecp256k1 != that1.SigVerifyCostSecp256k1 { return false } + if this.PubKeyChangeCost != that1.PubKeyChangeCost { + return false + } + if this.EnableChangePubKey != that1.EnableChangePubKey { + return false + } return true } func (m *BaseAccount) Marshal() (dAtA []byte, err error) { @@ -396,6 +423,21 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.EnableChangePubKey { + i-- + if m.EnableChangePubKey { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 + } + if m.PubKeyChangeCost != 0 { + i = encodeVarintAuth(dAtA, i, uint64(m.PubKeyChangeCost)) + i-- + dAtA[i] = 0x30 + } if m.SigVerifyCostSecp256k1 != 0 { i = encodeVarintAuth(dAtA, i, uint64(m.SigVerifyCostSecp256k1)) i-- @@ -502,6 +544,12 @@ func (m *Params) Size() (n int) { if m.SigVerifyCostSecp256k1 != 0 { n += 1 + sovAuth(uint64(m.SigVerifyCostSecp256k1)) } + if m.PubKeyChangeCost != 0 { + n += 1 + sovAuth(uint64(m.PubKeyChangeCost)) + } + if m.EnableChangePubKey { + n += 2 + } return n } @@ -947,6 +995,45 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PubKeyChangeCost", wireType) + } + m.PubKeyChangeCost = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PubKeyChangeCost |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EnableChangePubKey", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.EnableChangePubKey = bool(v != 0) default: iNdEx = preIndex skippy, err := skipAuth(dAtA[iNdEx:]) diff --git a/x/auth/types/params.go b/x/auth/types/params.go index 710ee963b4a3..b54572ffa1ce 100644 --- a/x/auth/types/params.go +++ b/x/auth/types/params.go @@ -15,6 +15,8 @@ const ( DefaultTxSizeCostPerByte uint64 = 10 DefaultSigVerifyCostED25519 uint64 = 590 DefaultSigVerifyCostSecp256k1 uint64 = 1000 + DefaultPubKeyChangeCost uint64 = 5000 + DefaultEnableChangePubKey bool = true ) // Parameter keys @@ -24,13 +26,15 @@ var ( KeyTxSizeCostPerByte = []byte("TxSizeCostPerByte") KeySigVerifyCostED25519 = []byte("SigVerifyCostED25519") KeySigVerifyCostSecp256k1 = []byte("SigVerifyCostSecp256k1") + KeyPubKeyChangeCost = []byte("PubKeyChangeCost") + KeyEnableChangePubKey = []byte("EnableChangePubKey") ) var _ paramtypes.ParamSet = &Params{} // NewParams creates a new Params object func NewParams( - maxMemoCharacters, txSigLimit, txSizeCostPerByte, sigVerifyCostED25519, sigVerifyCostSecp256k1 uint64, + maxMemoCharacters, txSigLimit, txSizeCostPerByte, sigVerifyCostED25519, sigVerifyCostSecp256k1 uint64, pubKeyChangeCost uint64, enableChangePubKey bool, ) Params { return Params{ MaxMemoCharacters: maxMemoCharacters, @@ -38,6 +42,8 @@ func NewParams( TxSizeCostPerByte: txSizeCostPerByte, SigVerifyCostED25519: sigVerifyCostED25519, SigVerifyCostSecp256k1: sigVerifyCostSecp256k1, + PubKeyChangeCost: pubKeyChangeCost, + EnableChangePubKey: enableChangePubKey, } } @@ -56,6 +62,8 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeyTxSizeCostPerByte, &p.TxSizeCostPerByte, validateTxSizeCostPerByte), paramtypes.NewParamSetPair(KeySigVerifyCostED25519, &p.SigVerifyCostED25519, validateSigVerifyCostED25519), paramtypes.NewParamSetPair(KeySigVerifyCostSecp256k1, &p.SigVerifyCostSecp256k1, validateSigVerifyCostSecp256k1), + paramtypes.NewParamSetPair(KeyPubKeyChangeCost, &p.PubKeyChangeCost, validatePubKeyChangeCost), + paramtypes.NewParamSetPair(KeyEnableChangePubKey, &p.EnableChangePubKey, validateEnableChangePubKey), } } @@ -67,6 +75,8 @@ func DefaultParams() Params { TxSizeCostPerByte: DefaultTxSizeCostPerByte, SigVerifyCostED25519: DefaultSigVerifyCostED25519, SigVerifyCostSecp256k1: DefaultSigVerifyCostSecp256k1, + PubKeyChangeCost: DefaultPubKeyChangeCost, + EnableChangePubKey: DefaultEnableChangePubKey, } } @@ -115,6 +125,24 @@ func validateSigVerifyCostSecp256k1(i interface{}) error { return nil } +func validatePubKeyChangeCost(i interface{}) error { + _, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + return nil +} + +func validateEnableChangePubKey(i interface{}) error { + _, ok := i.(bool) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + return nil +} + func validateMaxMemoCharacters(i interface{}) error { v, ok := i.(uint64) if !ok { @@ -152,6 +180,12 @@ func (p Params) Validate() error { if err := validateSigVerifyCostSecp256k1(p.SigVerifyCostSecp256k1); err != nil { return err } + if err := validatePubKeyChangeCost(p.PubKeyChangeCost); err != nil { + return err + } + if err := validateEnableChangePubKey(p.EnableChangePubKey); err != nil { + return err + } if err := validateMaxMemoCharacters(p.MaxMemoCharacters); err != nil { return err } diff --git a/x/auth/types/params_test.go b/x/auth/types/params_test.go index fcec36cb833c..c627ac51a44c 100644 --- a/x/auth/types/params_test.go +++ b/x/auth/types/params_test.go @@ -26,15 +26,15 @@ func TestParams_Validate(t *testing.T) { }{ {"default params", types.DefaultParams(), nil}, {"invalid tx signature limit", types.NewParams(types.DefaultMaxMemoCharacters, 0, types.DefaultTxSizeCostPerByte, - types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1), fmt.Errorf("invalid tx signature limit: 0")}, + types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1, types.DefaultPubKeyChangeCost, types.DefaultEnableChangePubKey), fmt.Errorf("invalid tx signature limit: 0")}, {"invalid ED25519 signature verification cost", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, - 0, types.DefaultSigVerifyCostSecp256k1), fmt.Errorf("invalid ED25519 signature verification cost: 0")}, + 0, types.DefaultSigVerifyCostSecp256k1, types.DefaultPubKeyChangeCost, types.DefaultEnableChangePubKey), fmt.Errorf("invalid ED25519 signature verification cost: 0")}, {"invalid SECK256k1 signature verification cost", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, - types.DefaultSigVerifyCostED25519, 0), fmt.Errorf("invalid SECK256k1 signature verification cost: 0")}, + types.DefaultSigVerifyCostED25519, 0, types.DefaultPubKeyChangeCost, types.DefaultEnableChangePubKey), fmt.Errorf("invalid SECK256k1 signature verification cost: 0")}, {"invalid max memo characters", types.NewParams(0, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, - types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1), fmt.Errorf("invalid max memo characters: 0")}, + types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1, types.DefaultPubKeyChangeCost, types.DefaultEnableChangePubKey), fmt.Errorf("invalid max memo characters: 0")}, {"invalid tx size cost per byte", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, 0, - types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1), fmt.Errorf("invalid tx size cost per byte: 0")}, + types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1, types.DefaultPubKeyChangeCost, types.DefaultEnableChangePubKey), fmt.Errorf("invalid tx size cost per byte: 0")}, } for _, tt := range tests { tt := tt diff --git a/x/staking/client/testutil/test_helpers.go b/x/staking/client/testutil/test_helpers.go index 1a2a4b84bcbf..e1e3e912d5dd 100644 --- a/x/staking/client/testutil/test_helpers.go +++ b/x/staking/client/testutil/test_helpers.go @@ -15,6 +15,7 @@ var commonArgs = []string{ fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--gas=%d", 210000), } // MsgRedelegateExec creates a redelegate message. diff --git a/x/staking/types/staking.pb.go b/x/staking/types/staking.pb.go index 8b54a0ed2989..554851aa3a59 100644 --- a/x/staking/types/staking.pb.go +++ b/x/staking/types/staking.pb.go @@ -1216,606 +1216,605 @@ func (this *Pool) Description() (desc *github_com_gogo_protobuf_protoc_gen_gogo_ func StakingDescription() (desc *github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet) { d := &github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet{} var gzipped = []byte{ - // 9584 bytes of a gzipped FileDescriptorSet + // 9558 bytes of a gzipped FileDescriptorSet 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x70, 0x24, 0xd7, 0x71, 0xd8, 0xcd, 0x7e, 0x00, 0xbb, 0x8d, 0x05, 0xb0, 0x78, 0xc0, 0xdd, 0xed, 0x2d, 0x8f, 0x00, 0x38, 0xfc, 0x3a, 0x1e, 0x49, 0x80, 0x3c, 0xf2, 0x8e, 0xc7, 0x3d, 0x89, 0x34, 0x16, 0xbb, 0x87, 0x03, 0x0f, 0x5f, 0x1c, 0x00, 0x47, 0x7d, 0x39, 0x5b, 0x83, 0xdd, 0x87, 0xc5, 0x10, 0xbb, 0x33, - 0xc3, 0x99, 0xd9, 0x3b, 0x80, 0x92, 0xaa, 0x68, 0x49, 0x51, 0xa4, 0x73, 0x1c, 0x49, 0x91, 0xcb, - 0x91, 0x68, 0x9d, 0x22, 0x59, 0x4e, 0xe4, 0xc8, 0x4a, 0xfc, 0x21, 0x45, 0x89, 0x93, 0x54, 0x45, - 0x4a, 0xe2, 0x58, 0x52, 0x2a, 0x2e, 0xa9, 0xe2, 0x4a, 0x1c, 0x57, 0x7c, 0x76, 0x28, 0x95, 0xc3, - 0x28, 0x4a, 0x2c, 0x9f, 0xe5, 0xc4, 0x29, 0xfd, 0x48, 0xea, 0x7d, 0xcd, 0xd7, 0x7e, 0xcc, 0x02, - 0xba, 0x13, 0xe5, 0x38, 0xbf, 0xb0, 0xd3, 0xaf, 0xbb, 0x5f, 0x77, 0xbf, 0xee, 0x7e, 0xfd, 0xde, - 0xbc, 0x37, 0x80, 0x7f, 0x79, 0x01, 0xa6, 0xeb, 0x86, 0x51, 0x6f, 0xe0, 0x59, 0xd3, 0x32, 0x1c, - 0x63, 0xab, 0xb5, 0x3d, 0x5b, 0xc3, 0x76, 0xd5, 0xd2, 0x4c, 0xc7, 0xb0, 0x66, 0x28, 0x0c, 0x8d, - 0x32, 0x8c, 0x19, 0x81, 0x21, 0x2f, 0xc3, 0xd8, 0x45, 0xad, 0x81, 0x4b, 0x2e, 0xe2, 0x3a, 0x76, - 0xd0, 0x79, 0x48, 0x6c, 0x6b, 0x0d, 0x9c, 0x93, 0xa6, 0xe3, 0xa7, 0x86, 0xce, 0xdc, 0x37, 0x13, - 0x22, 0x9a, 0x09, 0x52, 0xac, 0x11, 0xb0, 0x42, 0x29, 0xe4, 0x6f, 0x27, 0x60, 0xbc, 0x43, 0x2b, + 0xc3, 0x99, 0xd9, 0x3b, 0x80, 0x92, 0xaa, 0x68, 0x49, 0x51, 0xa4, 0x73, 0x1c, 0x49, 0x96, 0xcb, + 0x91, 0x28, 0x9d, 0x22, 0x59, 0x4e, 0xe4, 0xc8, 0x4a, 0xfc, 0x21, 0x45, 0x89, 0x93, 0x54, 0x45, + 0x4e, 0xc5, 0xb1, 0xa4, 0x54, 0x5c, 0x52, 0xc5, 0x95, 0x38, 0xae, 0xf8, 0xec, 0x50, 0x2a, 0x87, + 0x51, 0x94, 0x58, 0x3e, 0xcb, 0x89, 0x53, 0xfa, 0x91, 0xd4, 0xfb, 0x9a, 0xaf, 0xfd, 0x98, 0x05, + 0x74, 0x27, 0xca, 0x71, 0x7e, 0x61, 0x5f, 0x4f, 0x77, 0xbf, 0xee, 0x7e, 0xfd, 0xfa, 0xf5, 0xeb, + 0x79, 0x6f, 0x00, 0x9f, 0xb8, 0x00, 0xd3, 0x75, 0xc3, 0xa8, 0x37, 0xf0, 0xac, 0x69, 0x19, 0x8e, + 0xb1, 0xd5, 0xda, 0x9e, 0xad, 0x61, 0xbb, 0x6a, 0x69, 0xa6, 0x63, 0x58, 0x33, 0x14, 0x86, 0x46, + 0x19, 0xc6, 0x8c, 0xc0, 0x90, 0x97, 0x61, 0xec, 0xa2, 0xd6, 0xc0, 0x25, 0x17, 0x71, 0x1d, 0x3b, + 0xe8, 0x3c, 0x24, 0xb6, 0xb5, 0x06, 0xce, 0x49, 0xd3, 0xf1, 0x53, 0x43, 0x67, 0xee, 0x9b, 0x09, + 0x11, 0xcd, 0x04, 0x29, 0xd6, 0x08, 0x58, 0xa1, 0x14, 0xf2, 0xb7, 0x13, 0x30, 0xde, 0xe1, 0x29, 0x42, 0x90, 0xd0, 0xd5, 0x26, 0xe1, 0x28, 0x9d, 0x4a, 0x2b, 0xf4, 0x37, 0xca, 0xc1, 0xa0, 0xa9, - 0x56, 0x77, 0xd5, 0x3a, 0xce, 0xc5, 0x28, 0x58, 0x3c, 0xa2, 0x49, 0x80, 0x1a, 0x36, 0xb1, 0x5e, - 0xc3, 0x7a, 0x75, 0x3f, 0x17, 0x9f, 0x8e, 0x9f, 0x4a, 0x2b, 0x3e, 0x08, 0x7a, 0x18, 0xc6, 0xcc, - 0xd6, 0x56, 0x43, 0xab, 0x56, 0x7c, 0x68, 0x30, 0x1d, 0x3f, 0x95, 0x54, 0xb2, 0xac, 0xa1, 0xe4, + 0x56, 0x77, 0xd5, 0x3a, 0xce, 0xc5, 0x28, 0x58, 0x34, 0xd1, 0x24, 0x40, 0x0d, 0x9b, 0x58, 0xaf, + 0x61, 0xbd, 0xba, 0x9f, 0x8b, 0x4f, 0xc7, 0x4f, 0xa5, 0x15, 0x1f, 0x04, 0x3d, 0x0c, 0x63, 0x66, + 0x6b, 0xab, 0xa1, 0x55, 0x2b, 0x3e, 0x34, 0x98, 0x8e, 0x9f, 0x4a, 0x2a, 0x59, 0xf6, 0xa0, 0xe4, 0x21, 0x3f, 0x08, 0xa3, 0xd7, 0xb0, 0xba, 0xeb, 0x47, 0x1d, 0xa2, 0xa8, 0x23, 0x04, 0xec, 0x43, 0x9c, 0x87, 0x4c, 0x13, 0xdb, 0xb6, 0x5a, 0xc7, 0x15, 0x67, 0xdf, 0xc4, 0xb9, 0x04, 0xd5, 0x7e, 0xba, 0x4d, 0xfb, 0xb0, 0xe6, 0x43, 0x9c, 0x6a, 0x63, 0xdf, 0xc4, 0x68, 0x0e, 0xd2, 0x58, 0x6f, 0x35, 0x19, 0x87, 0x64, 0x17, 0xfb, 0x95, 0xf5, 0x56, 0x33, 0xcc, 0x25, 0x45, 0xc8, 0x38, 0x8b, - 0x41, 0x1b, 0x5b, 0x57, 0xb5, 0x2a, 0xce, 0x0d, 0x50, 0x06, 0x0f, 0xb6, 0x31, 0x58, 0x67, 0xed, - 0x61, 0x1e, 0x82, 0x0e, 0xcd, 0x43, 0x1a, 0xef, 0x39, 0x58, 0xb7, 0x35, 0x43, 0xcf, 0x0d, 0x52, - 0x26, 0xf7, 0x77, 0x18, 0x45, 0xdc, 0xa8, 0x85, 0x59, 0x78, 0x74, 0xe8, 0x1c, 0x0c, 0x1a, 0xa6, - 0xa3, 0x19, 0xba, 0x9d, 0x4b, 0x4d, 0x4b, 0xa7, 0x86, 0xce, 0x9c, 0xec, 0xe8, 0x08, 0xab, 0x0c, - 0x47, 0x11, 0xc8, 0x68, 0x11, 0xb2, 0xb6, 0xd1, 0xb2, 0xaa, 0xb8, 0x52, 0x35, 0x6a, 0xb8, 0xa2, - 0xe9, 0xdb, 0x46, 0x2e, 0x4d, 0x19, 0x4c, 0xb5, 0x2b, 0x42, 0x11, 0xe7, 0x8d, 0x1a, 0x5e, 0xd4, - 0xb7, 0x0d, 0x65, 0xc4, 0x0e, 0x3c, 0xa3, 0x63, 0x30, 0x60, 0xef, 0xeb, 0x8e, 0xba, 0x97, 0xcb, - 0x50, 0x0f, 0xe1, 0x4f, 0xf2, 0x6f, 0x0c, 0xc0, 0x68, 0x3f, 0x2e, 0x76, 0x01, 0x92, 0xdb, 0x44, - 0xcb, 0x5c, 0xec, 0x20, 0x36, 0x60, 0x34, 0x41, 0x23, 0x0e, 0x1c, 0xd2, 0x88, 0x73, 0x30, 0xa4, - 0x63, 0xdb, 0xc1, 0x35, 0xe6, 0x11, 0xf1, 0x3e, 0x7d, 0x0a, 0x18, 0x51, 0xbb, 0x4b, 0x25, 0x0e, - 0xe5, 0x52, 0x6f, 0x81, 0x51, 0x57, 0xa4, 0x8a, 0xa5, 0xea, 0x75, 0xe1, 0x9b, 0xb3, 0x51, 0x92, - 0xcc, 0x94, 0x05, 0x9d, 0x42, 0xc8, 0x94, 0x11, 0x1c, 0x78, 0x46, 0x25, 0x00, 0x43, 0xc7, 0xc6, - 0x76, 0xa5, 0x86, 0xab, 0x8d, 0x5c, 0xaa, 0x8b, 0x95, 0x56, 0x09, 0x4a, 0x9b, 0x95, 0x0c, 0x06, - 0xad, 0x36, 0xd0, 0xd3, 0x9e, 0xab, 0x0d, 0x76, 0xf1, 0x94, 0x65, 0x16, 0x64, 0x6d, 0xde, 0xb6, - 0x09, 0x23, 0x16, 0x26, 0x7e, 0x8f, 0x6b, 0x5c, 0xb3, 0x34, 0x15, 0x62, 0x26, 0x52, 0x33, 0x85, - 0x93, 0x31, 0xc5, 0x86, 0x2d, 0xff, 0x23, 0xba, 0x17, 0x5c, 0x40, 0x85, 0xba, 0x15, 0xd0, 0x2c, - 0x94, 0x11, 0xc0, 0x15, 0xb5, 0x89, 0xf3, 0x2f, 0xc3, 0x48, 0xd0, 0x3c, 0x68, 0x02, 0x92, 0xb6, - 0xa3, 0x5a, 0x0e, 0xf5, 0xc2, 0xa4, 0xc2, 0x1e, 0x50, 0x16, 0xe2, 0x58, 0xaf, 0xd1, 0x2c, 0x97, - 0x54, 0xc8, 0x4f, 0xf4, 0x13, 0x9e, 0xc2, 0x71, 0xaa, 0xf0, 0x03, 0xed, 0x23, 0x1a, 0xe0, 0x1c, - 0xd6, 0x3b, 0xff, 0x14, 0x0c, 0x07, 0x14, 0xe8, 0xb7, 0x6b, 0xf9, 0x5d, 0x70, 0xb4, 0x23, 0x6b, - 0xf4, 0x16, 0x98, 0x68, 0xe9, 0x9a, 0xee, 0x60, 0xcb, 0xb4, 0x30, 0xf1, 0x58, 0xd6, 0x55, 0xee, - 0xbf, 0x0c, 0x76, 0xf1, 0xb9, 0x4d, 0x3f, 0x36, 0xe3, 0xa2, 0x8c, 0xb7, 0xda, 0x81, 0xa7, 0xd3, - 0xa9, 0xd7, 0x07, 0xb3, 0xaf, 0xbc, 0xf2, 0xca, 0x2b, 0x31, 0xf9, 0x2b, 0x03, 0x30, 0xd1, 0x29, - 0x66, 0x3a, 0x86, 0xef, 0x31, 0x18, 0xd0, 0x5b, 0xcd, 0x2d, 0x6c, 0x51, 0x23, 0x25, 0x15, 0xfe, - 0x84, 0xe6, 0x20, 0xd9, 0x50, 0xb7, 0x70, 0x23, 0x97, 0x98, 0x96, 0x4e, 0x8d, 0x9c, 0x79, 0xb8, - 0xaf, 0xa8, 0x9c, 0x59, 0x22, 0x24, 0x0a, 0xa3, 0x44, 0xcf, 0x40, 0x82, 0xa7, 0x68, 0xc2, 0xe1, - 0x74, 0x7f, 0x1c, 0x48, 0x2c, 0x29, 0x94, 0x0e, 0xdd, 0x05, 0x69, 0xf2, 0x97, 0xf9, 0xc6, 0x00, - 0x95, 0x39, 0x45, 0x00, 0xc4, 0x2f, 0x50, 0x1e, 0x52, 0x34, 0x4c, 0x6a, 0x58, 0x4c, 0x6d, 0xee, - 0x33, 0x71, 0xac, 0x1a, 0xde, 0x56, 0x5b, 0x0d, 0xa7, 0x72, 0x55, 0x6d, 0xb4, 0x30, 0x75, 0xf8, - 0xb4, 0x92, 0xe1, 0xc0, 0x2b, 0x04, 0x86, 0xa6, 0x60, 0x88, 0x45, 0x95, 0xa6, 0xd7, 0xf0, 0x1e, - 0xcd, 0x9e, 0x49, 0x85, 0x05, 0xda, 0x22, 0x81, 0x90, 0xee, 0x5f, 0xb4, 0x0d, 0x5d, 0xb8, 0x26, - 0xed, 0x82, 0x00, 0x68, 0xf7, 0x4f, 0x85, 0x13, 0xf7, 0xdd, 0x9d, 0xd5, 0x6b, 0x8b, 0xa5, 0x07, - 0x61, 0x94, 0x62, 0x3c, 0xc1, 0x87, 0x5e, 0x6d, 0xe4, 0xc6, 0xa6, 0xa5, 0x53, 0x29, 0x65, 0x84, - 0x81, 0x57, 0x39, 0x54, 0xfe, 0x52, 0x0c, 0x12, 0x34, 0xb1, 0x8c, 0xc2, 0xd0, 0xc6, 0x5b, 0xd7, - 0xca, 0x95, 0xd2, 0xea, 0x66, 0x71, 0xa9, 0x9c, 0x95, 0xd0, 0x08, 0x00, 0x05, 0x5c, 0x5c, 0x5a, - 0x9d, 0xdb, 0xc8, 0xc6, 0xdc, 0xe7, 0xc5, 0x95, 0x8d, 0x73, 0x4f, 0x66, 0xe3, 0x2e, 0xc1, 0x26, - 0x03, 0x24, 0xfc, 0x08, 0x4f, 0x9c, 0xc9, 0x26, 0x51, 0x16, 0x32, 0x8c, 0xc1, 0xe2, 0x5b, 0xca, - 0xa5, 0x73, 0x4f, 0x66, 0x07, 0x82, 0x90, 0x27, 0xce, 0x64, 0x07, 0xd1, 0x30, 0xa4, 0x29, 0xa4, - 0xb8, 0xba, 0xba, 0x94, 0x4d, 0xb9, 0x3c, 0xd7, 0x37, 0x94, 0xc5, 0x95, 0x85, 0x6c, 0xda, 0xe5, - 0xb9, 0xa0, 0xac, 0x6e, 0xae, 0x65, 0xc1, 0xe5, 0xb0, 0x5c, 0x5e, 0x5f, 0x9f, 0x5b, 0x28, 0x67, - 0x87, 0x5c, 0x8c, 0xe2, 0x5b, 0x37, 0xca, 0xeb, 0xd9, 0x4c, 0x40, 0xac, 0x27, 0xce, 0x64, 0x87, - 0xdd, 0x2e, 0xca, 0x2b, 0x9b, 0xcb, 0xd9, 0x11, 0x34, 0x06, 0xc3, 0xac, 0x0b, 0x21, 0xc4, 0x68, - 0x08, 0x74, 0xee, 0xc9, 0x6c, 0xd6, 0x13, 0x84, 0x71, 0x19, 0x0b, 0x00, 0xce, 0x3d, 0x99, 0x45, - 0xf2, 0x3c, 0x24, 0xa9, 0x1b, 0x22, 0x04, 0x23, 0x4b, 0x73, 0xc5, 0xf2, 0x52, 0x65, 0x75, 0x6d, - 0x63, 0x71, 0x75, 0x65, 0x6e, 0x29, 0x2b, 0x79, 0x30, 0xa5, 0xfc, 0xfc, 0xe6, 0xa2, 0x52, 0x2e, - 0x65, 0x63, 0x7e, 0xd8, 0x5a, 0x79, 0x6e, 0xa3, 0x5c, 0xca, 0xc6, 0xe5, 0x2a, 0x4c, 0x74, 0x4a, - 0xa8, 0x1d, 0x43, 0xc8, 0xe7, 0x0b, 0xb1, 0x2e, 0xbe, 0x40, 0x79, 0x85, 0x7d, 0x41, 0xfe, 0x56, - 0x0c, 0xc6, 0x3b, 0x4c, 0x2a, 0x1d, 0x3b, 0x79, 0x16, 0x92, 0xcc, 0x97, 0xd9, 0x34, 0xfb, 0x50, - 0xc7, 0xd9, 0x89, 0x7a, 0x76, 0xdb, 0x54, 0x4b, 0xe9, 0xfc, 0xa5, 0x46, 0xbc, 0x4b, 0xa9, 0x41, - 0x58, 0xb4, 0x39, 0xec, 0x4f, 0xb6, 0x25, 0x7f, 0x36, 0x3f, 0x9e, 0xeb, 0x67, 0x7e, 0xa4, 0xb0, - 0x83, 0x4d, 0x02, 0xc9, 0x0e, 0x93, 0xc0, 0x05, 0x18, 0x6b, 0x63, 0xd4, 0x77, 0x32, 0x7e, 0xaf, - 0x04, 0xb9, 0x6e, 0xc6, 0x89, 0x48, 0x89, 0xb1, 0x40, 0x4a, 0xbc, 0x10, 0xb6, 0xe0, 0x3d, 0xdd, - 0x07, 0xa1, 0x6d, 0xac, 0x3f, 0x2b, 0xc1, 0xb1, 0xce, 0x25, 0x65, 0x47, 0x19, 0x9e, 0x81, 0x81, - 0x26, 0x76, 0x76, 0x0c, 0x51, 0x56, 0x3d, 0xd0, 0x61, 0xb2, 0x26, 0xcd, 0xe1, 0xc1, 0xe6, 0x54, - 0xfe, 0xd9, 0x3e, 0xde, 0xad, 0x2e, 0x64, 0xd2, 0xb4, 0x49, 0xfa, 0xc1, 0x18, 0x1c, 0xed, 0xc8, - 0xbc, 0xa3, 0xa0, 0x77, 0x03, 0x68, 0xba, 0xd9, 0x72, 0x58, 0xe9, 0xc4, 0x32, 0x71, 0x9a, 0x42, - 0x68, 0xf2, 0x22, 0x59, 0xb6, 0xe5, 0xb8, 0xed, 0x71, 0xda, 0x0e, 0x0c, 0x44, 0x11, 0xce, 0x7b, - 0x82, 0x26, 0xa8, 0xa0, 0x93, 0x5d, 0x34, 0x6d, 0x73, 0xcc, 0xc7, 0x20, 0x5b, 0x6d, 0x68, 0x58, - 0x77, 0x2a, 0xb6, 0x63, 0x61, 0xb5, 0xa9, 0xe9, 0x75, 0x3a, 0xd5, 0xa4, 0x0a, 0xc9, 0x6d, 0xb5, - 0x61, 0x63, 0x65, 0x94, 0x35, 0xaf, 0x8b, 0x56, 0x42, 0x41, 0x1d, 0xc8, 0xf2, 0x51, 0x0c, 0x04, - 0x28, 0x58, 0xb3, 0x4b, 0x21, 0x7f, 0x24, 0x0d, 0x43, 0xbe, 0x02, 0x1c, 0xdd, 0x03, 0x99, 0x17, - 0xd5, 0xab, 0x6a, 0x45, 0x2c, 0xaa, 0x98, 0x25, 0x86, 0x08, 0x6c, 0x8d, 0x2f, 0xac, 0x1e, 0x83, - 0x09, 0x8a, 0x62, 0xb4, 0x1c, 0x6c, 0x55, 0xaa, 0x0d, 0xd5, 0xb6, 0xa9, 0xd1, 0x52, 0x14, 0x15, - 0x91, 0xb6, 0x55, 0xd2, 0x34, 0x2f, 0x5a, 0xd0, 0x59, 0x18, 0xa7, 0x14, 0xcd, 0x56, 0xc3, 0xd1, - 0xcc, 0x06, 0xae, 0x90, 0x65, 0x9e, 0x4d, 0xa7, 0x1c, 0x57, 0xb2, 0x31, 0x82, 0xb1, 0xcc, 0x11, - 0x88, 0x44, 0x36, 0x2a, 0xc1, 0xdd, 0x94, 0xac, 0x8e, 0x75, 0x6c, 0xa9, 0x0e, 0xae, 0xe0, 0x97, - 0x5a, 0x6a, 0xc3, 0xae, 0xa8, 0x7a, 0xad, 0xb2, 0xa3, 0xda, 0x3b, 0xb9, 0x09, 0xc2, 0xa0, 0x18, - 0xcb, 0x49, 0xca, 0x09, 0x82, 0xb8, 0xc0, 0xf1, 0xca, 0x14, 0x6d, 0x4e, 0xaf, 0x5d, 0x52, 0xed, - 0x1d, 0x54, 0x80, 0x63, 0x94, 0x8b, 0xed, 0x58, 0x9a, 0x5e, 0xaf, 0x54, 0x77, 0x70, 0x75, 0xb7, - 0xd2, 0x72, 0xb6, 0xcf, 0xe7, 0xee, 0xf2, 0xf7, 0x4f, 0x25, 0x5c, 0xa7, 0x38, 0xf3, 0x04, 0x65, - 0xd3, 0xd9, 0x3e, 0x8f, 0xd6, 0x21, 0x43, 0x06, 0xa3, 0xa9, 0xbd, 0x8c, 0x2b, 0xdb, 0x86, 0x45, - 0xe7, 0xd0, 0x91, 0x0e, 0xa9, 0xc9, 0x67, 0xc1, 0x99, 0x55, 0x4e, 0xb0, 0x6c, 0xd4, 0x70, 0x21, - 0xb9, 0xbe, 0x56, 0x2e, 0x97, 0x94, 0x21, 0xc1, 0xe5, 0xa2, 0x61, 0x11, 0x87, 0xaa, 0x1b, 0xae, - 0x81, 0x87, 0x98, 0x43, 0xd5, 0x0d, 0x61, 0xde, 0xb3, 0x30, 0x5e, 0xad, 0x32, 0x9d, 0xb5, 0x6a, - 0x85, 0x2f, 0xc6, 0xec, 0x5c, 0x36, 0x60, 0xac, 0x6a, 0x75, 0x81, 0x21, 0x70, 0x1f, 0xb7, 0xd1, - 0xd3, 0x70, 0xd4, 0x33, 0x96, 0x9f, 0x70, 0xac, 0x4d, 0xcb, 0x30, 0xe9, 0x59, 0x18, 0x37, 0xf7, - 0xdb, 0x09, 0x51, 0xa0, 0x47, 0x73, 0x3f, 0x4c, 0xf6, 0x14, 0x4c, 0x98, 0x3b, 0x66, 0x3b, 0xdd, - 0x69, 0x3f, 0x1d, 0x32, 0x77, 0xcc, 0x30, 0xe1, 0xfd, 0x74, 0x65, 0x6e, 0xe1, 0xaa, 0xea, 0xe0, - 0x5a, 0xee, 0xb8, 0x1f, 0xdd, 0xd7, 0x80, 0x66, 0x20, 0x5b, 0xad, 0x56, 0xb0, 0xae, 0x6e, 0x35, - 0x70, 0x45, 0xb5, 0xb0, 0xae, 0xda, 0xb9, 0x29, 0x8a, 0x9c, 0x70, 0xac, 0x16, 0x56, 0x46, 0xaa, - 0xd5, 0x32, 0x6d, 0x9c, 0xa3, 0x6d, 0xe8, 0x34, 0x8c, 0x19, 0x5b, 0x2f, 0x56, 0x99, 0x47, 0x56, - 0x4c, 0x0b, 0x6f, 0x6b, 0x7b, 0xb9, 0xfb, 0xa8, 0x79, 0x47, 0x49, 0x03, 0xf5, 0xc7, 0x35, 0x0a, - 0x46, 0x0f, 0x41, 0xb6, 0x6a, 0xef, 0xa8, 0x96, 0x49, 0x53, 0xb2, 0x6d, 0xaa, 0x55, 0x9c, 0xbb, - 0x9f, 0xa1, 0x32, 0xf8, 0x8a, 0x00, 0x93, 0x88, 0xb0, 0xaf, 0x69, 0xdb, 0x8e, 0xe0, 0xf8, 0x20, - 0x8b, 0x08, 0x0a, 0xe3, 0xdc, 0x4e, 0x41, 0x96, 0x58, 0x22, 0xd0, 0xf1, 0x29, 0x8a, 0x36, 0x62, - 0xee, 0x98, 0xfe, 0x7e, 0xef, 0x85, 0x61, 0x82, 0xe9, 0x75, 0xfa, 0x10, 0x2b, 0xdc, 0xcc, 0x1d, - 0x5f, 0x8f, 0x4f, 0xc2, 0x31, 0x82, 0xd4, 0xc4, 0x8e, 0x5a, 0x53, 0x1d, 0xd5, 0x87, 0xfd, 0x08, - 0xc5, 0x26, 0x66, 0x5f, 0xe6, 0x8d, 0x01, 0x39, 0xad, 0xd6, 0xd6, 0xbe, 0xeb, 0x58, 0x8f, 0x32, - 0x39, 0x09, 0x4c, 0xb8, 0xd6, 0x1d, 0x2b, 0xce, 0xe5, 0x02, 0x64, 0xfc, 0x7e, 0x8f, 0xd2, 0xc0, - 0x3c, 0x3f, 0x2b, 0x91, 0x22, 0x68, 0x7e, 0xb5, 0x44, 0xca, 0x97, 0xb7, 0x95, 0xb3, 0x31, 0x52, - 0x46, 0x2d, 0x2d, 0x6e, 0x94, 0x2b, 0xca, 0xe6, 0xca, 0xc6, 0xe2, 0x72, 0x39, 0x1b, 0xf7, 0x15, - 0xf6, 0xcf, 0x25, 0x52, 0x0f, 0x64, 0x1f, 0x94, 0xbf, 0x19, 0x83, 0x91, 0xe0, 0x4a, 0x0d, 0xbd, - 0x09, 0x8e, 0x8b, 0x6d, 0x15, 0x1b, 0x3b, 0x95, 0x6b, 0x9a, 0x45, 0x03, 0xb2, 0xa9, 0xb2, 0xc9, - 0xd1, 0xf5, 0x9f, 0x09, 0x8e, 0xb5, 0x8e, 0x9d, 0x17, 0x34, 0x8b, 0x84, 0x5b, 0x53, 0x75, 0xd0, - 0x12, 0x4c, 0xe9, 0x46, 0xc5, 0x76, 0x54, 0xbd, 0xa6, 0x5a, 0xb5, 0x8a, 0xb7, 0xa1, 0x55, 0x51, - 0xab, 0x55, 0x6c, 0xdb, 0x06, 0x9b, 0x08, 0x5d, 0x2e, 0x27, 0x75, 0x63, 0x9d, 0x23, 0x7b, 0x33, - 0xc4, 0x1c, 0x47, 0x0d, 0xb9, 0x6f, 0xbc, 0x9b, 0xfb, 0xde, 0x05, 0xe9, 0xa6, 0x6a, 0x56, 0xb0, - 0xee, 0x58, 0xfb, 0xb4, 0x3e, 0x4f, 0x29, 0xa9, 0xa6, 0x6a, 0x96, 0xc9, 0xf3, 0x8f, 0x64, 0x99, - 0xf4, 0x5c, 0x22, 0x95, 0xca, 0xa6, 0x9f, 0x4b, 0xa4, 0xd2, 0x59, 0x90, 0x5f, 0x8b, 0x43, 0xc6, - 0x5f, 0xaf, 0x93, 0xe5, 0x4f, 0x95, 0xce, 0x58, 0x12, 0xcd, 0x69, 0xf7, 0xf6, 0xac, 0xee, 0x67, - 0xe6, 0xc9, 0x54, 0x56, 0x18, 0x60, 0xc5, 0xb1, 0xc2, 0x28, 0x49, 0x19, 0x41, 0x9c, 0x0d, 0xb3, - 0x62, 0x24, 0xa5, 0xf0, 0x27, 0xb4, 0x00, 0x03, 0x2f, 0xda, 0x94, 0xf7, 0x00, 0xe5, 0x7d, 0x5f, - 0x6f, 0xde, 0xcf, 0xad, 0x53, 0xe6, 0xe9, 0xe7, 0xd6, 0x2b, 0x2b, 0xab, 0xca, 0xf2, 0xdc, 0x92, - 0xc2, 0xc9, 0xd1, 0x09, 0x48, 0x34, 0xd4, 0x97, 0xf7, 0x83, 0x93, 0x1e, 0x05, 0xf5, 0x3b, 0x08, - 0x27, 0x20, 0x71, 0x0d, 0xab, 0xbb, 0xc1, 0xa9, 0x86, 0x82, 0xee, 0x60, 0x30, 0xcc, 0x42, 0x92, - 0xda, 0x0b, 0x01, 0x70, 0x8b, 0x65, 0x8f, 0xa0, 0x14, 0x24, 0xe6, 0x57, 0x15, 0x12, 0x10, 0x59, - 0xc8, 0x30, 0x68, 0x65, 0x6d, 0xb1, 0x3c, 0x5f, 0xce, 0xc6, 0xe4, 0xb3, 0x30, 0xc0, 0x8c, 0x40, - 0x82, 0xc5, 0x35, 0x43, 0xf6, 0x08, 0x7f, 0xe4, 0x3c, 0x24, 0xd1, 0xba, 0xb9, 0x5c, 0x2c, 0x2b, - 0xd9, 0x58, 0x70, 0xa8, 0x13, 0xd9, 0xa4, 0x6c, 0x43, 0xc6, 0x5f, 0x87, 0xff, 0x68, 0x16, 0xe3, - 0x5f, 0x96, 0x60, 0xc8, 0x57, 0x57, 0x93, 0x82, 0x48, 0x6d, 0x34, 0x8c, 0x6b, 0x15, 0xb5, 0xa1, - 0xa9, 0x36, 0x77, 0x0d, 0xa0, 0xa0, 0x39, 0x02, 0xe9, 0x77, 0xe8, 0x7e, 0x44, 0x21, 0x92, 0xcc, - 0x0e, 0xc8, 0x9f, 0x94, 0x20, 0x1b, 0x2e, 0x6c, 0x43, 0x62, 0x4a, 0x6f, 0xa4, 0x98, 0xf2, 0x27, - 0x24, 0x18, 0x09, 0x56, 0xb3, 0x21, 0xf1, 0xee, 0x79, 0x43, 0xc5, 0xfb, 0xc3, 0x18, 0x0c, 0x07, - 0x6a, 0xd8, 0x7e, 0xa5, 0x7b, 0x09, 0xc6, 0xb4, 0x1a, 0x6e, 0x9a, 0x86, 0x83, 0xf5, 0xea, 0x7e, - 0xa5, 0x81, 0xaf, 0xe2, 0x46, 0x4e, 0xa6, 0x49, 0x63, 0xb6, 0x77, 0x95, 0x3c, 0xb3, 0xe8, 0xd1, - 0x2d, 0x11, 0xb2, 0xc2, 0xf8, 0x62, 0xa9, 0xbc, 0xbc, 0xb6, 0xba, 0x51, 0x5e, 0x99, 0x7f, 0x6b, - 0x65, 0x73, 0xe5, 0xf2, 0xca, 0xea, 0x0b, 0x2b, 0x4a, 0x56, 0x0b, 0xa1, 0xdd, 0xc1, 0xb0, 0x5f, - 0x83, 0x6c, 0x58, 0x28, 0x74, 0x1c, 0x3a, 0x89, 0x95, 0x3d, 0x82, 0xc6, 0x61, 0x74, 0x65, 0xb5, - 0xb2, 0xbe, 0x58, 0x2a, 0x57, 0xca, 0x17, 0x2f, 0x96, 0xe7, 0x37, 0xd6, 0xd9, 0xbe, 0x87, 0x8b, - 0xbd, 0x11, 0x08, 0x70, 0xf9, 0xd5, 0x38, 0x8c, 0x77, 0x90, 0x04, 0xcd, 0xf1, 0x15, 0x0b, 0x5b, - 0x44, 0x3d, 0xda, 0x8f, 0xf4, 0x33, 0xa4, 0x66, 0x58, 0x53, 0x2d, 0x87, 0x2f, 0x70, 0x1e, 0x02, - 0x62, 0x25, 0xdd, 0xd1, 0xb6, 0x35, 0x6c, 0xf1, 0xfd, 0x24, 0xb6, 0x8c, 0x19, 0xf5, 0xe0, 0x6c, - 0x4b, 0xe9, 0x11, 0x40, 0xa6, 0x61, 0x6b, 0x8e, 0x76, 0x15, 0x57, 0x34, 0x5d, 0x6c, 0x3e, 0x91, - 0x65, 0x4d, 0x42, 0xc9, 0x8a, 0x96, 0x45, 0xdd, 0x71, 0xb1, 0x75, 0x5c, 0x57, 0x43, 0xd8, 0x24, - 0x99, 0xc7, 0x95, 0xac, 0x68, 0x71, 0xb1, 0xef, 0x81, 0x4c, 0xcd, 0x68, 0x91, 0x5a, 0x8f, 0xe1, - 0x91, 0xb9, 0x43, 0x52, 0x86, 0x18, 0xcc, 0x45, 0xe1, 0x55, 0xbc, 0xb7, 0xeb, 0x95, 0x51, 0x86, - 0x18, 0x8c, 0xa1, 0x3c, 0x08, 0xa3, 0x6a, 0xbd, 0x6e, 0x11, 0xe6, 0x82, 0x11, 0x5b, 0x97, 0x8c, - 0xb8, 0x60, 0x8a, 0x98, 0x7f, 0x0e, 0x52, 0xc2, 0x0e, 0x64, 0xaa, 0x26, 0x96, 0xa8, 0x98, 0x6c, - 0xb1, 0x1d, 0x3b, 0x95, 0x56, 0x52, 0xba, 0x68, 0xbc, 0x07, 0x32, 0x9a, 0x5d, 0xf1, 0x36, 0xf1, - 0x63, 0xd3, 0xb1, 0x53, 0x29, 0x65, 0x48, 0xb3, 0xdd, 0x0d, 0x50, 0xf9, 0xb3, 0x31, 0x18, 0x09, - 0xbe, 0x84, 0x40, 0x25, 0x48, 0x35, 0x8c, 0xaa, 0x4a, 0x5d, 0x8b, 0xbd, 0x01, 0x3b, 0x15, 0xf1, - 0xde, 0x62, 0x66, 0x89, 0xe3, 0x2b, 0x2e, 0x65, 0xfe, 0xb7, 0x25, 0x48, 0x09, 0x30, 0x3a, 0x06, - 0x09, 0x53, 0x75, 0x76, 0x28, 0xbb, 0x64, 0x31, 0x96, 0x95, 0x14, 0xfa, 0x4c, 0xe0, 0xb6, 0xa9, - 0xea, 0xd4, 0x05, 0x38, 0x9c, 0x3c, 0x93, 0x71, 0x6d, 0x60, 0xb5, 0x46, 0x17, 0x3d, 0x46, 0xb3, - 0x89, 0x75, 0xc7, 0x16, 0xe3, 0xca, 0xe1, 0xf3, 0x1c, 0x8c, 0x1e, 0x86, 0x31, 0xc7, 0x52, 0xb5, - 0x46, 0x00, 0x37, 0x41, 0x71, 0xb3, 0xa2, 0xc1, 0x45, 0x2e, 0xc0, 0x09, 0xc1, 0xb7, 0x86, 0x1d, - 0xb5, 0xba, 0x83, 0x6b, 0x1e, 0xd1, 0x00, 0xdd, 0xdc, 0x38, 0xce, 0x11, 0x4a, 0xbc, 0x5d, 0xd0, - 0xca, 0xdf, 0x94, 0x60, 0x4c, 0x2c, 0xd3, 0x6a, 0xae, 0xb1, 0x96, 0x01, 0x54, 0x5d, 0x37, 0x1c, - 0xbf, 0xb9, 0xda, 0x5d, 0xb9, 0x8d, 0x6e, 0x66, 0xce, 0x25, 0x52, 0x7c, 0x0c, 0xf2, 0x4d, 0x00, - 0xaf, 0xa5, 0xab, 0xd9, 0xa6, 0x60, 0x88, 0xbf, 0x61, 0xa2, 0xaf, 0x29, 0xd9, 0xc2, 0x1e, 0x18, - 0x88, 0xac, 0xe7, 0xd0, 0x04, 0x24, 0xb7, 0x70, 0x5d, 0xd3, 0xf9, 0xbe, 0x31, 0x7b, 0x10, 0xdb, - 0x2f, 0x09, 0x77, 0xfb, 0xa5, 0xf8, 0x21, 0x09, 0xc6, 0xab, 0x46, 0x33, 0x2c, 0x6f, 0x31, 0x1b, - 0xda, 0x5d, 0xb0, 0x2f, 0x49, 0x6f, 0x7b, 0xa6, 0xae, 0x39, 0x3b, 0xad, 0xad, 0x99, 0xaa, 0xd1, - 0x9c, 0xad, 0x1b, 0x0d, 0x55, 0xaf, 0x7b, 0xef, 0x59, 0xe9, 0x8f, 0xea, 0xa3, 0x75, 0xac, 0x3f, - 0x5a, 0x37, 0x7c, 0x6f, 0x5d, 0x2f, 0x78, 0x3f, 0xff, 0x5c, 0x92, 0x7e, 0x21, 0x16, 0x5f, 0x58, - 0x2b, 0x7e, 0x2e, 0x96, 0x5f, 0x60, 0xdd, 0xad, 0x09, 0xf3, 0x28, 0x78, 0xbb, 0x81, 0xab, 0x44, - 0x65, 0xf8, 0xce, 0xc3, 0x30, 0x51, 0x37, 0xea, 0x06, 0xe5, 0x38, 0x4b, 0x7e, 0xf1, 0x37, 0xb7, - 0x69, 0x17, 0x9a, 0x8f, 0x7c, 0xcd, 0x5b, 0x58, 0x81, 0x71, 0x8e, 0x5c, 0xa1, 0xaf, 0x8e, 0xd8, - 0xc2, 0x06, 0xf5, 0xdc, 0x55, 0xcb, 0xfd, 0xda, 0xb7, 0xe9, 0x84, 0xae, 0x8c, 0x71, 0x52, 0xd2, - 0xc6, 0xd6, 0x3e, 0x05, 0x05, 0x8e, 0x06, 0xf8, 0xb1, 0xb0, 0xc5, 0x56, 0x04, 0xc7, 0xdf, 0xe4, - 0x1c, 0xc7, 0x7d, 0x1c, 0xd7, 0x39, 0x69, 0x61, 0x1e, 0x86, 0x0f, 0xc2, 0xeb, 0x5f, 0x73, 0x5e, - 0x19, 0xec, 0x67, 0xb2, 0x00, 0xa3, 0x94, 0x49, 0xb5, 0x65, 0x3b, 0x46, 0x93, 0xe6, 0xc4, 0xde, - 0x6c, 0x7e, 0xeb, 0xdb, 0x2c, 0x8e, 0x46, 0x08, 0xd9, 0xbc, 0x4b, 0x55, 0x28, 0x00, 0x7d, 0x5b, - 0x56, 0xc3, 0xd5, 0x46, 0x04, 0x87, 0xaf, 0x72, 0x41, 0x5c, 0xfc, 0xc2, 0x15, 0x98, 0x20, 0xbf, - 0x69, 0xca, 0xf2, 0x4b, 0x12, 0xbd, 0x05, 0x97, 0xfb, 0xe6, 0x7b, 0x59, 0xa8, 0x8e, 0xbb, 0x0c, - 0x7c, 0x32, 0xf9, 0x46, 0xb1, 0x8e, 0x1d, 0x07, 0x5b, 0x76, 0x45, 0x6d, 0x74, 0x12, 0xcf, 0xb7, - 0x87, 0x91, 0xfb, 0xf8, 0x77, 0x83, 0xa3, 0xb8, 0xc0, 0x28, 0xe7, 0x1a, 0x8d, 0xc2, 0x26, 0x1c, - 0xef, 0xe0, 0x15, 0x7d, 0xf0, 0x7c, 0x95, 0xf3, 0x9c, 0x68, 0xf3, 0x0c, 0xc2, 0x76, 0x0d, 0x04, - 0xdc, 0x1d, 0xcb, 0x3e, 0x78, 0xfe, 0x3c, 0xe7, 0x89, 0x38, 0xad, 0x18, 0x52, 0xc2, 0xf1, 0x39, - 0x18, 0xbb, 0x8a, 0xad, 0x2d, 0xc3, 0xe6, 0xfb, 0x46, 0x7d, 0xb0, 0xfb, 0x04, 0x67, 0x37, 0xca, - 0x09, 0xe9, 0x46, 0x12, 0xe1, 0xf5, 0x34, 0xa4, 0xb6, 0xd5, 0x2a, 0xee, 0x83, 0xc5, 0x0d, 0xce, - 0x62, 0x90, 0xe0, 0x13, 0xd2, 0x39, 0xc8, 0xd4, 0x0d, 0x3e, 0x6b, 0x45, 0x93, 0x7f, 0x92, 0x93, - 0x0f, 0x09, 0x1a, 0xce, 0xc2, 0x34, 0xcc, 0x56, 0x83, 0x4c, 0x69, 0xd1, 0x2c, 0xfe, 0xb6, 0x60, - 0x21, 0x68, 0x38, 0x8b, 0x03, 0x98, 0xf5, 0x53, 0x82, 0x85, 0xed, 0xb3, 0xe7, 0xb3, 0x30, 0x64, - 0xe8, 0x8d, 0x7d, 0x43, 0xef, 0x47, 0x88, 0x4f, 0x73, 0x0e, 0xc0, 0x49, 0x08, 0x83, 0x0b, 0x90, - 0xee, 0x77, 0x20, 0xfe, 0xce, 0x77, 0x45, 0x78, 0x88, 0x11, 0x58, 0x80, 0x51, 0x91, 0xa0, 0x34, - 0x43, 0xef, 0x83, 0xc5, 0xdf, 0xe5, 0x2c, 0x46, 0x7c, 0x64, 0x5c, 0x0d, 0x07, 0xdb, 0x4e, 0x1d, - 0xf7, 0xc3, 0xe4, 0xb3, 0x42, 0x0d, 0x4e, 0xc2, 0x4d, 0xb9, 0x85, 0xf5, 0xea, 0x4e, 0x7f, 0x1c, - 0x7e, 0x49, 0x98, 0x52, 0xd0, 0x10, 0x16, 0xf3, 0x30, 0xdc, 0x54, 0x2d, 0x7b, 0x47, 0x6d, 0xf4, - 0x35, 0x1c, 0x7f, 0x8f, 0xf3, 0xc8, 0xb8, 0x44, 0xdc, 0x22, 0x2d, 0xfd, 0x20, 0x6c, 0x3e, 0x27, - 0x2c, 0xe2, 0x23, 0xe3, 0xa1, 0x67, 0x3b, 0x74, 0x93, 0xed, 0x20, 0xdc, 0x7e, 0x59, 0x84, 0x1e, - 0xa3, 0x5d, 0xf6, 0x73, 0xbc, 0x00, 0x69, 0x5b, 0x7b, 0xb9, 0x2f, 0x36, 0x9f, 0x17, 0x23, 0x4d, - 0x09, 0x08, 0xf1, 0x5b, 0xe1, 0x44, 0xc7, 0x69, 0xa2, 0x0f, 0x66, 0x7f, 0x9f, 0x33, 0x3b, 0xd6, - 0x61, 0xaa, 0xe0, 0x29, 0xe1, 0xa0, 0x2c, 0xff, 0x81, 0x48, 0x09, 0x38, 0xc4, 0x6b, 0x8d, 0xac, - 0x23, 0x6c, 0x75, 0xfb, 0x60, 0x56, 0xfb, 0x15, 0x61, 0x35, 0x46, 0x1b, 0xb0, 0xda, 0x06, 0x1c, - 0xe3, 0x1c, 0x0f, 0x36, 0xae, 0xbf, 0x2a, 0x12, 0x2b, 0xa3, 0xde, 0x0c, 0x8e, 0xee, 0xdb, 0x21, - 0xef, 0x9a, 0x53, 0x14, 0xac, 0x76, 0xa5, 0xa9, 0x9a, 0x7d, 0x70, 0xfe, 0x35, 0xce, 0x59, 0x64, - 0x7c, 0xb7, 0xe2, 0xb5, 0x97, 0x55, 0x93, 0x30, 0x7f, 0x0b, 0xe4, 0x04, 0xf3, 0x96, 0x6e, 0xe1, - 0xaa, 0x51, 0xd7, 0xb5, 0x97, 0x71, 0xad, 0x0f, 0xd6, 0xbf, 0x1e, 0x1a, 0xaa, 0x4d, 0x1f, 0x39, - 0xe1, 0xbc, 0x08, 0x59, 0xb7, 0x56, 0xa9, 0x68, 0x4d, 0xd3, 0xb0, 0x9c, 0x08, 0x8e, 0x5f, 0x10, - 0x23, 0xe5, 0xd2, 0x2d, 0x52, 0xb2, 0x42, 0x19, 0xd8, 0x9b, 0xe7, 0x7e, 0x5d, 0xf2, 0x8b, 0x9c, - 0xd1, 0xb0, 0x47, 0xc5, 0x13, 0x47, 0xd5, 0x68, 0x9a, 0xaa, 0xd5, 0x4f, 0xfe, 0xfb, 0x87, 0x22, - 0x71, 0x70, 0x12, 0x9e, 0x38, 0x9c, 0x7d, 0x13, 0x93, 0xd9, 0xbe, 0x0f, 0x0e, 0x5f, 0x12, 0x89, - 0x43, 0xd0, 0x70, 0x16, 0xa2, 0x60, 0xe8, 0x83, 0xc5, 0x3f, 0x12, 0x2c, 0x04, 0x0d, 0x61, 0xf1, - 0xbc, 0x37, 0xd1, 0x5a, 0xb8, 0xae, 0xd9, 0x8e, 0xc5, 0xca, 0xe4, 0xde, 0xac, 0xfe, 0xf1, 0x77, - 0x83, 0x45, 0x98, 0xe2, 0x23, 0x25, 0x99, 0x88, 0x6f, 0xbb, 0xd2, 0x55, 0x54, 0xb4, 0x60, 0xbf, - 0x21, 0x32, 0x91, 0x8f, 0x8c, 0xc8, 0xe6, 0xab, 0x10, 0x89, 0xd9, 0xab, 0x64, 0xed, 0xd0, 0x07, - 0xbb, 0x7f, 0x12, 0x12, 0x6e, 0x5d, 0xd0, 0x12, 0x9e, 0xbe, 0xfa, 0xa7, 0xa5, 0xef, 0xe2, 0xfd, - 0xbe, 0xbc, 0xf3, 0x9f, 0x86, 0xea, 0x9f, 0x4d, 0x46, 0xc9, 0x72, 0xc8, 0x68, 0xa8, 0x9e, 0x42, - 0x51, 0xe7, 0x8c, 0x72, 0x3f, 0xf5, 0x7d, 0xae, 0x6f, 0xb0, 0x9c, 0x2a, 0x2c, 0x11, 0x27, 0x0f, - 0x16, 0x3d, 0xd1, 0xcc, 0xde, 0xfb, 0x7d, 0xd7, 0xcf, 0x03, 0x35, 0x4f, 0xe1, 0x22, 0x0c, 0x07, - 0x0a, 0x9e, 0x68, 0x56, 0xef, 0xe3, 0xac, 0x32, 0xfe, 0x7a, 0xa7, 0x70, 0x16, 0x12, 0xa4, 0x78, - 0x89, 0x26, 0xff, 0xab, 0x9c, 0x9c, 0xa2, 0x17, 0xde, 0x0c, 0x29, 0x51, 0xb4, 0x44, 0x93, 0xbe, - 0x9f, 0x93, 0xba, 0x24, 0x84, 0x5c, 0x14, 0x2c, 0xd1, 0xe4, 0x7f, 0x4d, 0x90, 0x0b, 0x12, 0x42, - 0xde, 0xbf, 0x09, 0xbf, 0xfc, 0xd3, 0x09, 0x3e, 0xe9, 0x08, 0xdb, 0x5d, 0x80, 0x41, 0x5e, 0xa9, - 0x44, 0x53, 0x7f, 0x90, 0x77, 0x2e, 0x28, 0x0a, 0x4f, 0x41, 0xb2, 0x4f, 0x83, 0xff, 0x0c, 0x27, - 0x65, 0xf8, 0x85, 0x79, 0x18, 0xf2, 0x55, 0x27, 0xd1, 0xe4, 0x7f, 0x83, 0x93, 0xfb, 0xa9, 0x88, - 0xe8, 0xbc, 0x3a, 0x89, 0x66, 0xf0, 0x21, 0x21, 0x3a, 0xa7, 0x20, 0x66, 0x13, 0x85, 0x49, 0x34, - 0xf5, 0x87, 0x85, 0xd5, 0x05, 0x49, 0xe1, 0x59, 0x48, 0xbb, 0x93, 0x4d, 0x34, 0xfd, 0x47, 0x38, - 0xbd, 0x47, 0x43, 0x2c, 0xe0, 0x9b, 0xec, 0xa2, 0x59, 0xfc, 0x4d, 0x61, 0x01, 0x1f, 0x15, 0x09, - 0xa3, 0x70, 0x01, 0x13, 0xcd, 0xe9, 0xa3, 0x22, 0x8c, 0x42, 0xf5, 0x0b, 0x19, 0x4d, 0x9a, 0xf3, - 0xa3, 0x59, 0xfc, 0xac, 0x18, 0x4d, 0x8a, 0x4f, 0xc4, 0x08, 0x57, 0x04, 0xd1, 0x3c, 0xfe, 0x96, - 0x10, 0x23, 0x54, 0x10, 0x14, 0xd6, 0x00, 0xb5, 0x57, 0x03, 0xd1, 0xfc, 0x3e, 0xc6, 0xf9, 0x8d, - 0xb5, 0x15, 0x03, 0x85, 0x17, 0xe0, 0x58, 0xe7, 0x4a, 0x20, 0x9a, 0xeb, 0xc7, 0xbf, 0x1f, 0x5a, - 0xbb, 0xf9, 0x0b, 0x81, 0xc2, 0x86, 0x37, 0xa5, 0xf8, 0xab, 0x80, 0x68, 0xb6, 0xaf, 0x7e, 0x3f, - 0x98, 0xb8, 0xfd, 0x45, 0x40, 0x61, 0x0e, 0xc0, 0x9b, 0x80, 0xa3, 0x79, 0x7d, 0x82, 0xf3, 0xf2, - 0x11, 0x91, 0xd0, 0xe0, 0xf3, 0x6f, 0x34, 0xfd, 0x0d, 0x11, 0x1a, 0x9c, 0x82, 0x84, 0x86, 0x98, - 0x7a, 0xa3, 0xa9, 0x3f, 0x29, 0x42, 0x43, 0x90, 0x10, 0xcf, 0xf6, 0xcd, 0x6e, 0xd1, 0x1c, 0x3e, - 0x2d, 0x3c, 0xdb, 0x47, 0x55, 0x58, 0x81, 0xb1, 0xb6, 0x09, 0x31, 0x9a, 0xd5, 0x2f, 0x70, 0x56, - 0xd9, 0xf0, 0x7c, 0xe8, 0x9f, 0xbc, 0xf8, 0x64, 0x18, 0xcd, 0xed, 0x33, 0xa1, 0xc9, 0x8b, 0xcf, - 0x85, 0x85, 0x0b, 0x90, 0xd2, 0x5b, 0x8d, 0x06, 0x09, 0x1e, 0xd4, 0xfb, 0x6c, 0x60, 0xee, 0xbf, - 0xfe, 0x80, 0x5b, 0x47, 0x10, 0x14, 0xce, 0x42, 0x12, 0x37, 0xb7, 0x70, 0x2d, 0x8a, 0xf2, 0x3b, - 0x3f, 0x10, 0x09, 0x93, 0x60, 0x17, 0x9e, 0x05, 0x60, 0x5b, 0x23, 0xf4, 0xf5, 0x60, 0x04, 0xed, - 0x7f, 0xfb, 0x01, 0x3f, 0x8c, 0xe3, 0x91, 0x78, 0x0c, 0xd8, 0xd1, 0x9e, 0xde, 0x0c, 0xbe, 0x1b, - 0x64, 0x40, 0x47, 0xe4, 0x69, 0x18, 0x7c, 0xd1, 0x36, 0x74, 0x47, 0xad, 0x47, 0x51, 0xff, 0x77, - 0x4e, 0x2d, 0xf0, 0x89, 0xc1, 0x9a, 0x86, 0x85, 0x1d, 0xb5, 0x6e, 0x47, 0xd1, 0xfe, 0x0f, 0x4e, - 0xeb, 0x12, 0x10, 0xe2, 0xaa, 0x6a, 0x3b, 0xfd, 0xe8, 0xfd, 0xc7, 0x82, 0x58, 0x10, 0x10, 0xa1, - 0xc9, 0xef, 0x5d, 0xbc, 0x1f, 0x45, 0xfb, 0x3d, 0x21, 0x34, 0xc7, 0x2f, 0xbc, 0x19, 0xd2, 0xe4, - 0x27, 0x3b, 0x61, 0x17, 0x41, 0xfc, 0x27, 0x9c, 0xd8, 0xa3, 0x20, 0x3d, 0xdb, 0x4e, 0xcd, 0xd1, - 0xa2, 0x8d, 0x7d, 0x8b, 0x8f, 0xb4, 0xc0, 0x2f, 0xcc, 0xc1, 0x90, 0xed, 0xd4, 0x6a, 0x2d, 0x5e, - 0x9f, 0x46, 0x90, 0xff, 0xe9, 0x0f, 0xdc, 0x2d, 0x0b, 0x97, 0x86, 0x8c, 0xf6, 0xb5, 0x5d, 0xc7, - 0x34, 0xe8, 0x2b, 0x90, 0x28, 0x0e, 0xdf, 0xe7, 0x1c, 0x7c, 0x24, 0x85, 0x79, 0xc8, 0x10, 0x5d, - 0x2c, 0x6c, 0x62, 0xfa, 0xbe, 0x2a, 0x82, 0xc5, 0x9f, 0x71, 0x03, 0x04, 0x88, 0x8a, 0x3f, 0xf9, - 0xd5, 0xd7, 0x26, 0xa5, 0x6f, 0xbc, 0x36, 0x29, 0xfd, 0xe1, 0x6b, 0x93, 0xd2, 0x87, 0xbf, 0x35, - 0x79, 0xe4, 0x1b, 0xdf, 0x9a, 0x3c, 0xf2, 0xbb, 0xdf, 0x9a, 0x3c, 0xd2, 0x79, 0xdb, 0x18, 0x16, - 0x8c, 0x05, 0x83, 0x6d, 0x18, 0xbf, 0x4d, 0x0e, 0x6c, 0x17, 0xd7, 0x0d, 0x6f, 0xb7, 0xd6, 0x5d, - 0xe4, 0xc0, 0x9f, 0x49, 0x64, 0xc1, 0x1c, 0xdc, 0xcb, 0x55, 0xf5, 0xfd, 0x2e, 0x77, 0x75, 0xf2, - 0x1d, 0x37, 0x86, 0xe5, 0x37, 0x41, 0x7c, 0x4e, 0xdf, 0x47, 0x27, 0x58, 0xce, 0xab, 0xb4, 0xac, - 0x06, 0x3f, 0xf9, 0x35, 0x48, 0x9e, 0x37, 0xad, 0x06, 0x9a, 0xf0, 0x8e, 0x67, 0x4a, 0xa7, 0x32, - 0xfc, 0xcc, 0x65, 0x21, 0xf1, 0xbd, 0x4f, 0x4f, 0x1d, 0x29, 0xee, 0x86, 0x35, 0xfc, 0x72, 0xa4, - 0x96, 0xa9, 0x39, 0x7d, 0x9f, 0x2a, 0xb9, 0x26, 0xbd, 0x2d, 0x49, 0xfa, 0xb0, 0xc5, 0xc6, 0xf6, - 0x64, 0x78, 0x63, 0xfb, 0x05, 0xdc, 0x68, 0x5c, 0xd6, 0x8d, 0x6b, 0xfa, 0x06, 0x41, 0xdb, 0x1a, - 0x60, 0xc7, 0x88, 0xe1, 0xc3, 0x31, 0x98, 0x0a, 0xeb, 0x4d, 0x1c, 0xc7, 0x76, 0xd4, 0xa6, 0xd9, - 0xed, 0xa6, 0xd2, 0x05, 0x48, 0x6f, 0x08, 0x1c, 0x94, 0x83, 0x41, 0x1b, 0x57, 0x0d, 0xbd, 0x66, - 0x53, 0x65, 0xe3, 0x8a, 0x78, 0x24, 0xca, 0xea, 0xaa, 0x6e, 0xd8, 0xfc, 0x7c, 0x24, 0x7b, 0x28, - 0xfe, 0x9c, 0x74, 0xb0, 0x91, 0x1c, 0x71, 0xbb, 0x12, 0x9a, 0x3e, 0xdc, 0x6b, 0xfb, 0x9f, 0x5a, - 0xc1, 0x53, 0xc1, 0xb7, 0xd7, 0xdf, 0xaf, 0x49, 0xde, 0x13, 0x87, 0x13, 0x55, 0xc3, 0x6e, 0x1a, - 0x76, 0x85, 0x8d, 0x30, 0x7b, 0xe0, 0xc6, 0xc8, 0xf8, 0x9b, 0xfa, 0xd8, 0xff, 0xbf, 0x04, 0x23, - 0x34, 0x0a, 0xe8, 0xce, 0x27, 0x4d, 0x3c, 0x91, 0x73, 0xc5, 0xd7, 0xfe, 0x7d, 0x92, 0x7a, 0xcd, - 0xb0, 0x4b, 0x48, 0x8f, 0x76, 0x6c, 0xc0, 0x84, 0xd6, 0x34, 0x1b, 0x98, 0xbe, 0x03, 0xaa, 0xb8, - 0x6d, 0xd1, 0xfc, 0xbe, 0xce, 0xf9, 0x8d, 0x7b, 0xe4, 0x8b, 0x82, 0xba, 0xb0, 0x04, 0x63, 0x6a, - 0xb5, 0x8a, 0xcd, 0x00, 0xcb, 0x88, 0x08, 0x15, 0x02, 0x66, 0x39, 0xa5, 0xcb, 0xad, 0xf8, 0x6c, - 0xb7, 0xb1, 0x7d, 0xdb, 0xfd, 0xbe, 0x41, 0xb3, 0x70, 0x1d, 0xeb, 0x8f, 0xea, 0xd8, 0xb9, 0x66, - 0x58, 0xbb, 0xdc, 0xbc, 0x8f, 0xb2, 0xae, 0xc4, 0x20, 0xbc, 0x2f, 0x0e, 0x93, 0xac, 0x61, 0x76, - 0x4b, 0xb5, 0xf1, 0xec, 0xd5, 0xc7, 0xb7, 0xb0, 0xa3, 0x3e, 0x3e, 0x5b, 0x35, 0x34, 0x9d, 0x8f, - 0xc4, 0x38, 0x1f, 0x17, 0xd2, 0x3e, 0xc3, 0xdb, 0xbb, 0x04, 0xe6, 0x02, 0x24, 0xe6, 0x0d, 0x4d, - 0x27, 0x1e, 0x59, 0xc3, 0xba, 0xd1, 0xe4, 0x61, 0xc9, 0x1e, 0xd0, 0xbd, 0x30, 0xa0, 0x36, 0x8d, - 0x96, 0xee, 0xb0, 0xd7, 0x57, 0xc5, 0xa1, 0xaf, 0xde, 0x9c, 0x3a, 0xf2, 0x7b, 0x37, 0xa7, 0xe2, - 0x8b, 0xba, 0xa3, 0xf0, 0xa6, 0x42, 0xe2, 0xf5, 0x4f, 0x4d, 0x49, 0xf2, 0x73, 0x30, 0x58, 0xc2, - 0xd5, 0xc3, 0xf0, 0x2a, 0xe1, 0x6a, 0x88, 0xd7, 0x43, 0x90, 0x5a, 0xd4, 0x1d, 0x76, 0x64, 0xf6, - 0x6e, 0x88, 0x6b, 0x3a, 0x3b, 0x85, 0x15, 0xea, 0x9f, 0xc0, 0x09, 0x6a, 0x09, 0x57, 0x5d, 0xd4, - 0x1a, 0xae, 0x86, 0x51, 0x09, 0x7b, 0x02, 0x2f, 0x96, 0x7e, 0xf7, 0x3f, 0x4f, 0x1e, 0x79, 0xe5, - 0xb5, 0xc9, 0x23, 0x5d, 0x47, 0xc2, 0x9f, 0x0e, 0xb9, 0x89, 0xf9, 0x10, 0xd8, 0xb5, 0xdd, 0x59, - 0x27, 0x10, 0x0b, 0x7f, 0x3d, 0x06, 0x93, 0x6d, 0x2e, 0xce, 0x27, 0x86, 0x6e, 0xd9, 0xa1, 0x00, - 0xa9, 0x92, 0x98, 0x6f, 0x0e, 0x9a, 0x1c, 0x7e, 0xf6, 0x80, 0xc9, 0x61, 0x58, 0xf4, 0x24, 0x72, - 0xc3, 0xe9, 0xe8, 0xdc, 0x20, 0xe4, 0x3f, 0x44, 0x6a, 0xf8, 0x5c, 0x02, 0xee, 0xa6, 0x97, 0x47, - 0xac, 0xa6, 0xa6, 0x3b, 0xb3, 0x55, 0x6b, 0xdf, 0x74, 0xe8, 0x74, 0x62, 0x6c, 0x73, 0x6b, 0x8c, - 0x79, 0xcd, 0x33, 0xac, 0xb9, 0x8b, 0x4b, 0x6e, 0x43, 0x72, 0x8d, 0xd0, 0x11, 0x43, 0x38, 0x86, - 0xa3, 0x36, 0xb8, 0x81, 0xd8, 0x03, 0x81, 0xb2, 0x0b, 0x27, 0x31, 0x06, 0xd5, 0xc4, 0x5d, 0x93, - 0x06, 0x56, 0xb7, 0xd9, 0xb9, 0xdd, 0x38, 0x9d, 0x42, 0x52, 0x04, 0x40, 0x8f, 0xe8, 0x4e, 0x40, - 0x52, 0x6d, 0xb1, 0x57, 0xce, 0x71, 0x32, 0xb7, 0xd0, 0x07, 0xf9, 0x32, 0x0c, 0xf2, 0xd7, 0x5c, - 0x28, 0x0b, 0xf1, 0x5d, 0xbc, 0x4f, 0xfb, 0xc9, 0x28, 0xe4, 0x27, 0x9a, 0x81, 0x24, 0x15, 0x9e, - 0x5f, 0x48, 0xc8, 0xcd, 0xb4, 0x49, 0x3f, 0x43, 0x85, 0x54, 0x18, 0x9a, 0xfc, 0x1c, 0xa4, 0x4a, - 0x46, 0x53, 0xd3, 0x8d, 0x20, 0xb7, 0x34, 0xe3, 0x46, 0x65, 0x36, 0x5b, 0xdc, 0xf5, 0x15, 0xf6, - 0x80, 0x8e, 0xc1, 0x00, 0x3b, 0xc7, 0xcd, 0x5f, 0x9b, 0xf3, 0x27, 0x79, 0x1e, 0x06, 0x29, 0xef, - 0x55, 0x13, 0x21, 0x7e, 0x03, 0x88, 0x1f, 0x18, 0xa7, 0x59, 0x92, 0xb3, 0x8f, 0x79, 0xc2, 0x22, - 0x48, 0xd4, 0x54, 0x47, 0xe5, 0x7a, 0xd3, 0xdf, 0xf2, 0x33, 0x90, 0xe2, 0x4c, 0x6c, 0x74, 0x06, - 0xe2, 0x86, 0x69, 0xf3, 0x17, 0xdf, 0xf9, 0x6e, 0xaa, 0xac, 0x9a, 0xc5, 0x04, 0x09, 0x1a, 0x85, - 0x20, 0x17, 0x95, 0xae, 0x51, 0x72, 0xde, 0xe7, 0x48, 0xbe, 0x21, 0xf7, 0xfd, 0x64, 0x43, 0xda, - 0xe6, 0x0e, 0xae, 0xb3, 0x7c, 0x3a, 0x06, 0x93, 0xbe, 0xd6, 0xab, 0xd8, 0x22, 0x6b, 0x3d, 0x16, - 0x60, 0xdc, 0x5b, 0x90, 0x4f, 0x48, 0xde, 0xde, 0xc5, 0x5d, 0xde, 0x0c, 0xf1, 0x39, 0xd3, 0x44, - 0x79, 0x48, 0xb1, 0x17, 0xdc, 0x06, 0xf3, 0x97, 0x84, 0xe2, 0x3e, 0x93, 0x36, 0xdb, 0xd8, 0x76, - 0xae, 0xa9, 0x96, 0x7b, 0xd5, 0x49, 0x3c, 0xcb, 0x4f, 0x43, 0x7a, 0xde, 0xd0, 0x6d, 0xac, 0xdb, - 0x2d, 0x1a, 0x7a, 0x5b, 0x0d, 0xa3, 0xba, 0xcb, 0x39, 0xb0, 0x07, 0x62, 0x70, 0xd5, 0x34, 0x29, - 0x65, 0x42, 0x21, 0x3f, 0x59, 0x9a, 0x2a, 0xae, 0x77, 0x35, 0xd1, 0xd3, 0x07, 0x37, 0x11, 0x57, - 0xd2, 0xb5, 0xd1, 0xef, 0x4b, 0x70, 0xb2, 0x3d, 0xa0, 0x76, 0xf1, 0xbe, 0x7d, 0xd0, 0x78, 0x3a, - 0x0f, 0xe9, 0x35, 0x7a, 0xdf, 0xf8, 0x32, 0xde, 0x47, 0x79, 0x18, 0xc4, 0xb5, 0x33, 0x67, 0xcf, - 0x3e, 0xfe, 0x34, 0xf3, 0xf6, 0x4b, 0x47, 0x14, 0x01, 0x28, 0xa4, 0x88, 0x56, 0xaf, 0x7f, 0x7a, - 0x4a, 0x2a, 0x26, 0x21, 0x6e, 0xb7, 0x9a, 0x77, 0xd4, 0x07, 0x5e, 0x4d, 0xc2, 0xb4, 0x9f, 0x92, - 0x26, 0xa0, 0xab, 0x6a, 0x43, 0xab, 0xa9, 0xde, 0x4d, 0xf0, 0xac, 0x4f, 0x47, 0x8a, 0xd1, 0x59, - 0xc5, 0x7c, 0x4f, 0x4b, 0xc9, 0xbf, 0x2e, 0x41, 0xe6, 0x8a, 0xe0, 0xbc, 0x8e, 0x1d, 0x74, 0x01, - 0xc0, 0xed, 0x49, 0x84, 0xc5, 0x5d, 0x33, 0xe1, 0xbe, 0x66, 0x5c, 0x1a, 0xc5, 0x87, 0x8e, 0x9e, - 0xa2, 0x8e, 0x66, 0x1a, 0x36, 0xbf, 0xde, 0x12, 0x41, 0xea, 0x22, 0xa3, 0x47, 0x00, 0xd1, 0x0c, - 0x56, 0xb9, 0x6a, 0x38, 0x9a, 0x5e, 0xaf, 0x98, 0xc6, 0x35, 0x7e, 0x69, 0x30, 0xae, 0x64, 0x69, - 0xcb, 0x15, 0xda, 0xb0, 0x46, 0xe0, 0x44, 0xe8, 0xb4, 0xcb, 0x85, 0xcc, 0x16, 0x6a, 0xad, 0x66, - 0x61, 0xdb, 0xe6, 0x49, 0x4a, 0x3c, 0xa2, 0x0b, 0x30, 0x68, 0xb6, 0xb6, 0x2a, 0x22, 0x23, 0x0c, - 0x9d, 0x39, 0xd9, 0x29, 0xbe, 0xc5, 0xf8, 0xf3, 0x08, 0x1f, 0x30, 0x5b, 0x5b, 0xc4, 0x1b, 0xee, - 0x81, 0x4c, 0x07, 0x61, 0x86, 0xae, 0x7a, 0x72, 0xd0, 0x6b, 0xec, 0x5c, 0x83, 0x8a, 0x69, 0x69, - 0x86, 0xa5, 0x39, 0xfb, 0xf4, 0x74, 0x4a, 0x5c, 0xc9, 0x8a, 0x86, 0x35, 0x0e, 0x97, 0x77, 0x61, - 0x74, 0x9d, 0x96, 0x52, 0x9e, 0xe4, 0x67, 0x3d, 0xf9, 0xa4, 0x68, 0xf9, 0xba, 0x4a, 0x16, 0x6b, - 0x93, 0xac, 0xf8, 0x7c, 0x57, 0xef, 0x7c, 0xea, 0xe0, 0xde, 0x19, 0x9c, 0xdc, 0xff, 0xf8, 0x44, - 0x20, 0xf8, 0x78, 0xe5, 0xec, 0x4b, 0x4f, 0xfd, 0x3a, 0x66, 0xd4, 0x0a, 0x22, 0xdf, 0x7b, 0xd2, - 0xcc, 0x47, 0xa4, 0xc9, 0x7c, 0x64, 0x08, 0xc9, 0x4f, 0xc3, 0xf0, 0x9a, 0x6a, 0x39, 0xeb, 0xd8, - 0xb9, 0x84, 0xd5, 0x1a, 0xb6, 0x82, 0xb3, 0xea, 0xb0, 0x98, 0x55, 0x11, 0x24, 0xe8, 0xd4, 0xc9, - 0x66, 0x15, 0xfa, 0x5b, 0xde, 0x81, 0x04, 0x3d, 0xa1, 0xe6, 0xce, 0xb8, 0x9c, 0x82, 0xcd, 0xb8, - 0x24, 0x57, 0xee, 0x3b, 0xd8, 0x16, 0x0b, 0x36, 0xfa, 0x80, 0x9e, 0x14, 0xf3, 0x66, 0xbc, 0xf7, - 0xbc, 0xc9, 0x1d, 0x91, 0xcf, 0x9e, 0x0d, 0x18, 0x2c, 0x92, 0x54, 0xbb, 0x58, 0x72, 0x05, 0x91, - 0x3c, 0x41, 0xd0, 0x32, 0x8c, 0x9a, 0xaa, 0xe5, 0xd0, 0xa3, 0xf9, 0x3b, 0x54, 0x0b, 0xee, 0xeb, - 0x53, 0xed, 0x91, 0x17, 0x50, 0x96, 0xf7, 0x32, 0x6c, 0xfa, 0x81, 0xf2, 0x1f, 0x25, 0x60, 0x80, - 0x1b, 0xe3, 0xcd, 0x30, 0xc8, 0xcd, 0xca, 0xbd, 0xf3, 0xee, 0x99, 0xf6, 0x89, 0x67, 0xc6, 0x9d, - 0x20, 0x38, 0x3f, 0x41, 0x83, 0x1e, 0x80, 0x54, 0x75, 0x47, 0xd5, 0xf4, 0x8a, 0x56, 0x13, 0x55, - 0xed, 0x6b, 0x37, 0xa7, 0x06, 0xe7, 0x09, 0x6c, 0xb1, 0xa4, 0x0c, 0xd2, 0xc6, 0xc5, 0x1a, 0x99, - 0xe9, 0x77, 0xb0, 0x56, 0xdf, 0x71, 0x78, 0x84, 0xf1, 0x27, 0x74, 0x1e, 0x12, 0xc4, 0x21, 0xf8, - 0xc5, 0xad, 0x7c, 0xdb, 0xda, 0xc2, 0x5d, 0xe0, 0x15, 0x53, 0xa4, 0xe3, 0x0f, 0xff, 0xc1, 0x94, - 0xa4, 0x50, 0x0a, 0x34, 0x0f, 0xc3, 0x0d, 0xd5, 0x76, 0x2a, 0x74, 0x86, 0x22, 0xdd, 0x27, 0x29, - 0x8b, 0x13, 0xed, 0x06, 0xe1, 0x86, 0xe5, 0xa2, 0x0f, 0x11, 0x2a, 0x06, 0xaa, 0xa1, 0x53, 0x90, - 0xa5, 0x4c, 0xaa, 0x46, 0xb3, 0xa9, 0x39, 0xac, 0x76, 0x1a, 0xa0, 0x76, 0x1f, 0x21, 0xf0, 0x79, - 0x0a, 0xa6, 0x15, 0xd4, 0x5d, 0x90, 0xa6, 0x57, 0x45, 0x28, 0x0a, 0x3b, 0x16, 0x99, 0x22, 0x00, - 0xda, 0xf8, 0x20, 0x8c, 0x7a, 0xf9, 0x91, 0xa1, 0xa4, 0x18, 0x17, 0x0f, 0x4c, 0x11, 0x1f, 0x83, - 0x09, 0x1d, 0xef, 0xd1, 0x83, 0x9a, 0x01, 0xec, 0x34, 0xc5, 0x46, 0xa4, 0xed, 0x4a, 0x90, 0xe2, - 0x7e, 0x18, 0xa9, 0x0a, 0xe3, 0x33, 0x5c, 0xa0, 0xb8, 0xc3, 0x2e, 0x94, 0xa2, 0x9d, 0x80, 0x94, - 0x6a, 0x9a, 0x0c, 0x61, 0x88, 0xe7, 0x47, 0xd3, 0xa4, 0x4d, 0xa7, 0x61, 0x8c, 0xea, 0x68, 0x61, - 0xbb, 0xd5, 0x70, 0x38, 0x93, 0x0c, 0xc5, 0x19, 0x25, 0x0d, 0x0a, 0x83, 0x53, 0xdc, 0x7b, 0x61, - 0x18, 0x5f, 0xd5, 0x6a, 0x58, 0xaf, 0x62, 0x86, 0x37, 0x4c, 0xf1, 0x32, 0x02, 0x48, 0x91, 0x1e, - 0x02, 0x37, 0xef, 0x55, 0x44, 0x4e, 0x1e, 0x61, 0xfc, 0x04, 0x7c, 0x8e, 0x81, 0xe5, 0x1c, 0x24, - 0x4a, 0xaa, 0xa3, 0x92, 0x02, 0xc2, 0xd9, 0x63, 0x13, 0x4d, 0x46, 0x21, 0x3f, 0xe5, 0xd7, 0x63, - 0x90, 0xb8, 0x62, 0x38, 0x18, 0x3d, 0xe1, 0x2b, 0xf0, 0x46, 0x3a, 0xf9, 0xf3, 0xba, 0x56, 0xd7, - 0x71, 0x6d, 0xd9, 0xae, 0xfb, 0xee, 0x75, 0x7b, 0xee, 0x14, 0x0b, 0xb8, 0xd3, 0x04, 0x24, 0x2d, - 0xa3, 0xa5, 0xd7, 0xc4, 0x89, 0x42, 0xfa, 0x80, 0xca, 0x90, 0x72, 0xbd, 0x24, 0x11, 0xe5, 0x25, - 0xa3, 0xc4, 0x4b, 0x88, 0x0f, 0x73, 0x80, 0x32, 0xb8, 0xc5, 0x9d, 0xa5, 0x08, 0x69, 0x37, 0x79, - 0x71, 0x6f, 0xeb, 0xcf, 0x61, 0x3d, 0x32, 0x32, 0x99, 0xb8, 0x63, 0xef, 0x1a, 0x8f, 0x79, 0x5c, - 0xd6, 0x6d, 0xe0, 0xd6, 0x0b, 0xb8, 0x15, 0xbf, 0x63, 0x3e, 0x48, 0xf5, 0xf2, 0xdc, 0x8a, 0xdd, - 0x33, 0x3f, 0x09, 0x69, 0x5b, 0xab, 0xeb, 0xaa, 0xd3, 0xb2, 0x30, 0xf7, 0x3c, 0x0f, 0x20, 0x7f, - 0x59, 0x82, 0x01, 0xe6, 0xc9, 0x3e, 0xbb, 0x49, 0x9d, 0xed, 0x16, 0xeb, 0x66, 0xb7, 0xf8, 0xe1, - 0xed, 0x36, 0x07, 0xe0, 0x0a, 0x63, 0xf3, 0xab, 0xbf, 0x1d, 0x2a, 0x06, 0x26, 0xe2, 0xba, 0x56, - 0xe7, 0x81, 0xea, 0x23, 0x92, 0x7f, 0x5f, 0x22, 0x45, 0x2a, 0x6f, 0x47, 0x73, 0x30, 0x2c, 0xe4, - 0xaa, 0x6c, 0x37, 0xd4, 0x3a, 0xf7, 0x9d, 0xbb, 0xbb, 0x0a, 0x77, 0xb1, 0xa1, 0xd6, 0x95, 0x21, - 0x2e, 0x0f, 0x79, 0xe8, 0x3c, 0x0e, 0xb1, 0x2e, 0xe3, 0x10, 0x18, 0xf8, 0xf8, 0xe1, 0x06, 0x3e, - 0x30, 0x44, 0x89, 0xf0, 0x10, 0x7d, 0x21, 0x46, 0x17, 0x2b, 0xa6, 0x61, 0xab, 0x8d, 0x1f, 0x45, - 0x44, 0xdc, 0x05, 0x69, 0xd3, 0x68, 0x54, 0x58, 0x0b, 0x3b, 0x69, 0x9b, 0x32, 0x8d, 0x86, 0xd2, - 0x36, 0xec, 0xc9, 0xdb, 0x14, 0x2e, 0x03, 0xb7, 0xc1, 0x6a, 0x83, 0x61, 0xab, 0x59, 0x90, 0x61, - 0xa6, 0xe0, 0x73, 0xd9, 0x63, 0xc4, 0x06, 0x74, 0x72, 0x94, 0xda, 0xe7, 0x5e, 0x26, 0x36, 0xc3, - 0x54, 0x38, 0x1e, 0xa1, 0x60, 0xa9, 0xbf, 0xd3, 0x2a, 0xd7, 0xef, 0x96, 0x0a, 0xc7, 0x93, 0x7f, - 0x4e, 0x02, 0x58, 0x22, 0x96, 0xa5, 0xfa, 0x92, 0x59, 0xc8, 0xa6, 0x22, 0x54, 0x02, 0x3d, 0x4f, - 0x76, 0x1b, 0x34, 0xde, 0x7f, 0xc6, 0xf6, 0xcb, 0x3d, 0x0f, 0xc3, 0x9e, 0x33, 0xda, 0x58, 0x08, - 0x33, 0xd9, 0xa3, 0xaa, 0x5e, 0xc7, 0x8e, 0x92, 0xb9, 0xea, 0x7b, 0x92, 0xff, 0x85, 0x04, 0x69, - 0x2a, 0xd3, 0x32, 0x76, 0xd4, 0xc0, 0x18, 0x4a, 0x87, 0x1f, 0xc3, 0xbb, 0x01, 0x18, 0x1b, 0x5b, - 0x7b, 0x19, 0x73, 0xcf, 0x4a, 0x53, 0xc8, 0xba, 0xf6, 0x32, 0x46, 0xe7, 0x5c, 0x83, 0xc7, 0x7b, - 0x1b, 0x5c, 0x54, 0xdd, 0xdc, 0xec, 0xc7, 0x61, 0x90, 0x7e, 0x2a, 0x67, 0xcf, 0xe6, 0x85, 0xf4, - 0x80, 0xde, 0x6a, 0x6e, 0xec, 0xd9, 0xf2, 0x8b, 0x30, 0xb8, 0xb1, 0xc7, 0xf6, 0x3e, 0xee, 0x82, - 0xb4, 0x65, 0x18, 0x7c, 0x4e, 0x66, 0xb5, 0x50, 0x8a, 0x00, 0xe8, 0x14, 0x24, 0xd6, 0xfb, 0x31, - 0x6f, 0xbd, 0xef, 0x6d, 0x58, 0xc4, 0xfb, 0xda, 0xb0, 0x38, 0xfd, 0x1f, 0x24, 0x18, 0xf2, 0xe5, - 0x07, 0xf4, 0x38, 0x1c, 0x2d, 0x2e, 0xad, 0xce, 0x5f, 0xae, 0x2c, 0x96, 0x2a, 0x17, 0x97, 0xe6, - 0x16, 0xbc, 0xbb, 0x24, 0xf9, 0x63, 0xd7, 0x6f, 0x4c, 0x23, 0x1f, 0xee, 0xa6, 0xbe, 0xab, 0x1b, - 0xd7, 0x74, 0x34, 0x0b, 0x13, 0x41, 0x92, 0xb9, 0xe2, 0x7a, 0x79, 0x65, 0x23, 0x2b, 0xe5, 0x8f, - 0x5e, 0xbf, 0x31, 0x3d, 0xe6, 0xa3, 0x98, 0xdb, 0xb2, 0xb1, 0xee, 0xb4, 0x13, 0xcc, 0xaf, 0x2e, - 0x2f, 0x2f, 0x6e, 0x64, 0x63, 0x6d, 0x04, 0x3c, 0x61, 0x3f, 0x04, 0x63, 0x41, 0x82, 0x95, 0xc5, - 0xa5, 0x6c, 0x3c, 0x8f, 0xae, 0xdf, 0x98, 0x1e, 0xf1, 0x61, 0xaf, 0x68, 0x8d, 0x7c, 0xea, 0x03, - 0x9f, 0x99, 0x3c, 0xf2, 0x4b, 0xbf, 0x38, 0x29, 0x11, 0xcd, 0x86, 0x03, 0x39, 0x02, 0x3d, 0x02, - 0xc7, 0xd7, 0x17, 0x17, 0x56, 0xca, 0xa5, 0xca, 0xf2, 0xfa, 0x42, 0x85, 0x7d, 0x43, 0xc3, 0xd5, - 0x6e, 0xf4, 0xfa, 0x8d, 0xe9, 0x21, 0xae, 0x52, 0x37, 0xec, 0x35, 0xa5, 0x7c, 0x65, 0x75, 0xa3, - 0x9c, 0x95, 0x18, 0xf6, 0x9a, 0x85, 0xaf, 0x1a, 0x0e, 0xfb, 0x96, 0xd6, 0x63, 0x70, 0xa2, 0x03, - 0xb6, 0xab, 0xd8, 0xd8, 0xf5, 0x1b, 0xd3, 0xc3, 0x6b, 0x16, 0x66, 0xf1, 0x43, 0x29, 0x66, 0x20, - 0xd7, 0x4e, 0xb1, 0xba, 0xb6, 0xba, 0x3e, 0xb7, 0x94, 0x9d, 0xce, 0x67, 0xaf, 0xdf, 0x98, 0xce, - 0x88, 0x64, 0x48, 0xf0, 0x3d, 0xcd, 0xee, 0xe4, 0x8a, 0xe7, 0x4f, 0x1f, 0x85, 0xfb, 0xf8, 0x96, - 0xa7, 0xed, 0xa8, 0xbb, 0x9a, 0x5e, 0x77, 0x37, 0x96, 0xf9, 0x33, 0x5f, 0xf9, 0x1c, 0xe3, 0x7b, - 0xcb, 0x02, 0xda, 0x73, 0x7b, 0x39, 0xdf, 0xfd, 0xcd, 0x51, 0x3e, 0x62, 0xf7, 0x34, 0x7a, 0xe9, - 0xd4, 0xfd, 0x55, 0x44, 0x3e, 0x62, 0x83, 0x3c, 0xdf, 0x73, 0x71, 0x27, 0x7f, 0x50, 0x82, 0x91, - 0x4b, 0x9a, 0xed, 0x18, 0x96, 0x56, 0x55, 0x1b, 0xf4, 0x06, 0xc9, 0xb9, 0x7e, 0x73, 0x6b, 0x28, - 0xd4, 0x9f, 0x85, 0x81, 0xab, 0x6a, 0x83, 0x25, 0xb5, 0x38, 0xfd, 0xe0, 0x45, 0x67, 0xf3, 0x79, - 0xa9, 0x4d, 0x30, 0x60, 0x64, 0xf2, 0xaf, 0xc4, 0x60, 0x94, 0x06, 0x83, 0xcd, 0x3e, 0x85, 0x44, - 0xd6, 0x58, 0x45, 0x48, 0x58, 0xaa, 0xc3, 0x37, 0x05, 0x8b, 0x33, 0x7c, 0xa3, 0xfb, 0x81, 0xe8, - 0xcd, 0xeb, 0x99, 0x12, 0xae, 0x2a, 0x94, 0x16, 0xbd, 0x03, 0x52, 0x4d, 0x75, 0xaf, 0x42, 0xf9, - 0xb0, 0x95, 0xcb, 0xdc, 0xc1, 0xf8, 0xdc, 0xba, 0x39, 0x35, 0xba, 0xaf, 0x36, 0x1b, 0x05, 0x59, - 0xf0, 0x91, 0x95, 0xc1, 0xa6, 0xba, 0x47, 0x44, 0x44, 0x26, 0x8c, 0x12, 0x68, 0x75, 0x47, 0xd5, - 0xeb, 0x98, 0x75, 0x42, 0xb7, 0x38, 0x8b, 0x97, 0x0e, 0xdc, 0xc9, 0x31, 0xaf, 0x13, 0x1f, 0x3b, - 0x59, 0x19, 0x6e, 0xaa, 0x7b, 0xf3, 0x14, 0x40, 0x7a, 0x2c, 0xa4, 0x3e, 0xf6, 0xa9, 0xa9, 0x23, - 0xf4, 0xe5, 0xc1, 0x37, 0x25, 0x00, 0xcf, 0x62, 0xe8, 0x1d, 0x90, 0xad, 0xba, 0x4f, 0x94, 0xd6, - 0xe6, 0x63, 0xf8, 0x60, 0xb7, 0xb1, 0x08, 0xd9, 0x9b, 0xcd, 0xcd, 0xdf, 0xb8, 0x39, 0x25, 0x29, - 0xa3, 0xd5, 0xd0, 0x50, 0xbc, 0x1d, 0x86, 0x5a, 0x66, 0x4d, 0x75, 0x70, 0x85, 0xae, 0xe3, 0x62, - 0x91, 0xf3, 0xfc, 0x24, 0xe1, 0x75, 0xeb, 0xe6, 0x14, 0x62, 0x6a, 0xf9, 0x88, 0x65, 0x3a, 0xfb, - 0x03, 0x83, 0x10, 0x02, 0x9f, 0x4e, 0x5f, 0x93, 0x60, 0xa8, 0xe4, 0x3b, 0xc9, 0x95, 0x83, 0xc1, - 0xa6, 0xa1, 0x6b, 0xbb, 0xdc, 0x1f, 0xd3, 0x8a, 0x78, 0x44, 0x79, 0x48, 0xb1, 0x4b, 0x75, 0xce, - 0xbe, 0xd8, 0xea, 0x14, 0xcf, 0x84, 0xea, 0x1a, 0xde, 0xb2, 0x35, 0x31, 0x1a, 0x8a, 0x78, 0x44, - 0x17, 0x21, 0x6b, 0xe3, 0x6a, 0xcb, 0xd2, 0x9c, 0xfd, 0x4a, 0xd5, 0xd0, 0x1d, 0xb5, 0xea, 0xb0, - 0xeb, 0x59, 0xc5, 0xbb, 0x6e, 0xdd, 0x9c, 0x3a, 0xce, 0x64, 0x0d, 0x63, 0xc8, 0xca, 0xa8, 0x00, - 0xcd, 0x33, 0x08, 0xe9, 0xa1, 0x86, 0x1d, 0x55, 0x6b, 0xd8, 0x39, 0xf6, 0x1e, 0x4c, 0x3c, 0xfa, - 0x74, 0xf9, 0xfc, 0xa0, 0x7f, 0x63, 0xeb, 0x22, 0x64, 0x0d, 0x13, 0x5b, 0x81, 0x42, 0x54, 0x0a, - 0xf7, 0x1c, 0xc6, 0x90, 0x95, 0x51, 0x01, 0x12, 0x45, 0xaa, 0x43, 0x86, 0x59, 0x2c, 0x14, 0xcd, - 0xd6, 0x96, 0xb7, 0x1f, 0x36, 0xd1, 0x36, 0x1a, 0x73, 0xfa, 0x7e, 0xf1, 0x09, 0x8f, 0x7b, 0x98, - 0x4e, 0xfe, 0xfa, 0x17, 0x1f, 0x9d, 0xe0, 0xae, 0xe1, 0xed, 0x4f, 0x5d, 0xc6, 0xfb, 0x64, 0xf8, - 0x39, 0xea, 0x1a, 0xc5, 0x24, 0x65, 0xe7, 0x8b, 0xaa, 0xd6, 0x10, 0xd7, 0x8c, 0x15, 0xfe, 0x84, - 0x0a, 0x30, 0x60, 0x3b, 0xaa, 0xd3, 0xb2, 0xf9, 0xc7, 0xbf, 0xe4, 0x6e, 0xae, 0x56, 0x34, 0xf4, - 0xda, 0x3a, 0xc5, 0x54, 0x38, 0x05, 0xba, 0x08, 0x03, 0x8e, 0xb1, 0x8b, 0x75, 0x6e, 0xc2, 0x03, - 0xc5, 0x37, 0x7d, 0x2d, 0xc7, 0xa8, 0x89, 0x45, 0x6a, 0xb8, 0x81, 0xeb, 0xac, 0xac, 0xda, 0x51, - 0xc9, 0xea, 0x83, 0x7e, 0x03, 0xac, 0xb8, 0x78, 0xe0, 0x20, 0xe4, 0x96, 0x0a, 0xf3, 0x93, 0x95, - 0x51, 0x17, 0xb4, 0x4e, 0x21, 0xe8, 0x72, 0xe0, 0xc8, 0x21, 0xff, 0x50, 0xde, 0xbd, 0xdd, 0xd4, - 0xf7, 0xf9, 0xb4, 0xd8, 0x9f, 0xf0, 0x1f, 0x58, 0xbc, 0x08, 0xd9, 0x96, 0xbe, 0x65, 0xe8, 0xf4, - 0x2e, 0x20, 0xaf, 0xef, 0xc9, 0xfa, 0x2e, 0xee, 0x77, 0x8e, 0x30, 0x86, 0xac, 0x8c, 0xba, 0xa0, - 0x4b, 0x6c, 0x15, 0x50, 0x83, 0x11, 0x0f, 0x8b, 0x06, 0x6a, 0x3a, 0x32, 0x50, 0xef, 0xe1, 0x81, - 0x7a, 0x34, 0xdc, 0x8b, 0x17, 0xab, 0xc3, 0x2e, 0x90, 0x90, 0xa1, 0x4b, 0x00, 0x5e, 0x7a, 0xa0, - 0xfb, 0x14, 0x43, 0xdd, 0x07, 0xde, 0xcb, 0x31, 0x62, 0xbd, 0xe7, 0xd1, 0xa2, 0x77, 0xc1, 0x78, - 0x53, 0xd3, 0x2b, 0x36, 0x6e, 0x6c, 0x57, 0xb8, 0x81, 0x09, 0x4b, 0xfa, 0x29, 0x97, 0xe2, 0xd2, - 0xc1, 0xfc, 0xe1, 0xd6, 0xcd, 0xa9, 0x3c, 0x4f, 0xa1, 0xed, 0x2c, 0x65, 0x65, 0xac, 0xa9, 0xe9, - 0xeb, 0xb8, 0xb1, 0x5d, 0x72, 0x61, 0x85, 0xcc, 0x07, 0x3e, 0x35, 0x75, 0x84, 0x87, 0xeb, 0x11, - 0xf9, 0x1c, 0xdd, 0x3b, 0xe7, 0x61, 0x86, 0x6d, 0xb2, 0x26, 0x51, 0xc5, 0x03, 0xdd, 0xd1, 0x48, - 0x2b, 0x1e, 0x80, 0x85, 0xf9, 0x2b, 0xff, 0x69, 0x5a, 0x92, 0x3f, 0x2f, 0xc1, 0x40, 0xe9, 0xca, - 0x9a, 0xaa, 0x59, 0x68, 0x11, 0xc6, 0x3c, 0xcf, 0x09, 0x06, 0xf9, 0xc9, 0x5b, 0x37, 0xa7, 0x72, - 0x61, 0xe7, 0x72, 0xa3, 0xdc, 0x73, 0x60, 0x11, 0xe6, 0x8b, 0xdd, 0x16, 0xae, 0x01, 0x56, 0x6d, - 0x28, 0x72, 0xfb, 0xb2, 0x36, 0xa4, 0x66, 0x19, 0x06, 0x99, 0xb4, 0x36, 0x2a, 0x40, 0xd2, 0x24, - 0x3f, 0xf8, 0x8b, 0x81, 0xc9, 0xae, 0xce, 0x4b, 0xf1, 0xdd, 0x8d, 0x4c, 0x42, 0x22, 0x7f, 0x24, - 0x06, 0x50, 0xba, 0x72, 0x65, 0xc3, 0xd2, 0xcc, 0x06, 0x76, 0x6e, 0xa7, 0xe6, 0x1b, 0x70, 0xd4, - 0xb7, 0x4a, 0xb2, 0xaa, 0x21, 0xed, 0xa7, 0x6f, 0xdd, 0x9c, 0x3a, 0x19, 0xd6, 0xde, 0x87, 0x26, - 0x2b, 0xe3, 0xde, 0x7a, 0xc9, 0xaa, 0x76, 0xe4, 0x5a, 0xb3, 0x1d, 0x97, 0x6b, 0xbc, 0x3b, 0x57, - 0x1f, 0x9a, 0x9f, 0x6b, 0xc9, 0x76, 0x3a, 0x9b, 0x76, 0x1d, 0x86, 0x3c, 0x93, 0xd8, 0xa8, 0x04, - 0x29, 0x87, 0xff, 0xe6, 0x16, 0x96, 0xbb, 0x5b, 0x58, 0x90, 0x71, 0x2b, 0xbb, 0x94, 0xf2, 0x9f, - 0x4b, 0x00, 0x9e, 0xcf, 0xfe, 0x78, 0xba, 0x18, 0x49, 0xe5, 0x3c, 0xf1, 0xc6, 0x0f, 0x55, 0xaa, - 0x71, 0xea, 0x90, 0x3d, 0x7f, 0x3a, 0x06, 0xe3, 0x9b, 0x22, 0xf3, 0xfc, 0xd8, 0xdb, 0x60, 0x0d, - 0x06, 0xb1, 0xee, 0x58, 0x1a, 0x35, 0x02, 0x19, 0xed, 0xc7, 0xba, 0x8d, 0x76, 0x07, 0x9d, 0xe8, - 0xc7, 0x6c, 0xc4, 0xa6, 0x3b, 0x67, 0x13, 0xb2, 0xc6, 0x87, 0xe2, 0x90, 0xeb, 0x46, 0x89, 0xe6, - 0x61, 0xb4, 0x6a, 0x61, 0x0a, 0xa8, 0xf8, 0x77, 0xfe, 0x8a, 0x79, 0xaf, 0xb2, 0x0c, 0x21, 0xc8, - 0xca, 0x88, 0x80, 0xf0, 0xd9, 0xa3, 0x0e, 0xa4, 0xec, 0x23, 0x6e, 0x47, 0xb0, 0xfa, 0xac, 0xf3, - 0x64, 0x3e, 0x7d, 0x88, 0x4e, 0x82, 0x0c, 0xd8, 0xfc, 0x31, 0xe2, 0x41, 0xe9, 0x04, 0xf2, 0x12, - 0x8c, 0x6a, 0xba, 0xe6, 0x68, 0x6a, 0xa3, 0xb2, 0xa5, 0x36, 0x54, 0xbd, 0x7a, 0x98, 0xaa, 0x99, - 0xa5, 0x7c, 0xde, 0x6d, 0x88, 0x9d, 0xac, 0x8c, 0x70, 0x48, 0x91, 0x01, 0xd0, 0x25, 0x18, 0x14, - 0x5d, 0x25, 0x0e, 0x55, 0x6d, 0x08, 0x72, 0x5f, 0x81, 0xf7, 0x33, 0x71, 0x18, 0x53, 0x70, 0xed, - 0xff, 0x0f, 0xc5, 0xc1, 0x86, 0x62, 0x19, 0x80, 0x85, 0x3b, 0x49, 0xb0, 0x87, 0x18, 0x0d, 0x92, - 0x30, 0xd2, 0x8c, 0x43, 0xc9, 0x76, 0x7c, 0xe3, 0x71, 0x33, 0x06, 0x19, 0xff, 0x78, 0xfc, 0x25, - 0x9d, 0x95, 0xd0, 0xa2, 0x97, 0x89, 0x12, 0xfc, 0x13, 0xa0, 0x5d, 0x32, 0x51, 0x9b, 0xf7, 0xf6, - 0x4e, 0x41, 0xff, 0x33, 0x06, 0x03, 0x6b, 0xaa, 0xa5, 0x36, 0x6d, 0x54, 0x6d, 0xab, 0x34, 0xc5, - 0xf6, 0x63, 0xdb, 0x87, 0x9e, 0xf9, 0x6e, 0x47, 0x44, 0xa1, 0xf9, 0xb1, 0x0e, 0x85, 0xe6, 0x4f, - 0xc0, 0x08, 0x59, 0x0e, 0xfb, 0x8e, 0x30, 0x10, 0x6b, 0x0f, 0x17, 0x4f, 0x78, 0x5c, 0x82, 0xed, - 0x6c, 0xb5, 0x7c, 0xc5, 0x7f, 0x86, 0x61, 0x88, 0x60, 0x78, 0x89, 0x99, 0x90, 0x1f, 0xf3, 0x96, - 0xa5, 0xbe, 0x46, 0x59, 0x81, 0xa6, 0xba, 0x57, 0x66, 0x0f, 0x68, 0x09, 0xd0, 0x8e, 0xbb, 0x33, - 0x52, 0xf1, 0xcc, 0x49, 0xe8, 0xef, 0xbe, 0x75, 0x73, 0xea, 0x04, 0xa3, 0x6f, 0xc7, 0x91, 0x95, - 0x31, 0x0f, 0x28, 0xb8, 0x3d, 0x09, 0x40, 0xf4, 0xaa, 0xb0, 0xd3, 0x82, 0x6c, 0xb9, 0x73, 0xf4, - 0xd6, 0xcd, 0xa9, 0x31, 0xc6, 0xc5, 0x6b, 0x93, 0x95, 0x34, 0x79, 0x28, 0x91, 0xdf, 0x3e, 0xcf, - 0xfe, 0x8c, 0x04, 0xc8, 0x4b, 0xf9, 0x0a, 0xb6, 0x4d, 0xb2, 0x3e, 0x23, 0x85, 0xb8, 0xaf, 0x6a, - 0x96, 0x7a, 0x17, 0xe2, 0x1e, 0xbd, 0x28, 0xc4, 0x7d, 0x91, 0xf2, 0xb4, 0x97, 0x1e, 0x63, 0x7c, - 0x1c, 0x3b, 0x1c, 0xad, 0x9c, 0x99, 0x37, 0x34, 0x41, 0xdd, 0x96, 0x0f, 0x8f, 0xc8, 0xff, 0x46, - 0x82, 0x13, 0x6d, 0x1e, 0xe5, 0x0a, 0xfb, 0x57, 0x00, 0x59, 0xbe, 0x46, 0xfe, 0x3d, 0x37, 0x26, - 0xf4, 0x81, 0x1d, 0x74, 0xcc, 0x6a, 0xcb, 0xbb, 0xb7, 0x2f, 0xc3, 0xb3, 0xb3, 0x99, 0xff, 0x5c, - 0x82, 0x09, 0x7f, 0xf7, 0xae, 0x22, 0x2b, 0x90, 0xf1, 0xf7, 0xce, 0x55, 0xb8, 0xaf, 0x1f, 0x15, - 0xb8, 0xf4, 0x01, 0x7a, 0xf4, 0xbc, 0x17, 0xae, 0x6c, 0xef, 0xec, 0xf1, 0xbe, 0xad, 0x21, 0x64, - 0x0a, 0x87, 0x6d, 0x82, 0x8e, 0xc7, 0xff, 0x91, 0x20, 0xb1, 0x66, 0x18, 0x0d, 0x64, 0xc0, 0x98, - 0x6e, 0x38, 0x15, 0xe2, 0x59, 0xb8, 0x56, 0xe1, 0x8b, 0x6e, 0x96, 0x07, 0xe7, 0x0f, 0x66, 0xa4, - 0xef, 0xdc, 0x9c, 0x6a, 0x67, 0xa5, 0x8c, 0xea, 0x86, 0x53, 0xa4, 0x90, 0x0d, 0xb6, 0x24, 0x7f, - 0x17, 0x0c, 0x07, 0x3b, 0x63, 0x59, 0xf2, 0x85, 0x03, 0x77, 0x16, 0x64, 0x73, 0xeb, 0xe6, 0xd4, - 0x84, 0x17, 0x31, 0x2e, 0x58, 0x56, 0x32, 0x5b, 0xbe, 0xde, 0xd9, 0xf1, 0xae, 0xef, 0x7d, 0x6a, - 0x4a, 0x3a, 0xfd, 0x25, 0x09, 0xc0, 0xdb, 0x79, 0x40, 0x8f, 0xc0, 0xf1, 0xe2, 0xea, 0x4a, 0xa9, - 0xb2, 0xbe, 0x31, 0xb7, 0xb1, 0xb9, 0x5e, 0xd9, 0x5c, 0x59, 0x5f, 0x2b, 0xcf, 0x2f, 0x5e, 0x5c, - 0x2c, 0x97, 0xbc, 0xed, 0x71, 0xdb, 0xc4, 0x55, 0x6d, 0x5b, 0xc3, 0x35, 0xf4, 0x00, 0x4c, 0x04, - 0xb1, 0xc9, 0x53, 0xb9, 0x94, 0x95, 0xf2, 0x99, 0xeb, 0x37, 0xa6, 0x53, 0xac, 0x16, 0xc3, 0x35, - 0x74, 0x0a, 0x8e, 0xb6, 0xe3, 0x2d, 0xae, 0x2c, 0x64, 0x63, 0xf9, 0xe1, 0xeb, 0x37, 0xa6, 0xd3, - 0x6e, 0xd1, 0x86, 0x64, 0x40, 0x7e, 0x4c, 0xce, 0x2f, 0x9e, 0x87, 0xeb, 0x37, 0xa6, 0x07, 0x98, - 0x01, 0xf3, 0x89, 0x0f, 0x7c, 0x66, 0xf2, 0x48, 0xf1, 0x62, 0xd7, 0x0d, 0xf0, 0x47, 0x7a, 0xda, - 0x6e, 0xcf, 0xdd, 0xd4, 0x0e, 0xee, 0x7a, 0x5f, 0x3f, 0x0e, 0x53, 0x5d, 0x76, 0xbd, 0x9d, 0xbd, - 0x88, 0x0d, 0xef, 0x1e, 0x5b, 0xdb, 0x91, 0x5b, 0xd7, 0x5d, 0x36, 0xcb, 0x0f, 0xbf, 0xa1, 0xdd, - 0xd7, 0xde, 0xbd, 0xfc, 0x6f, 0x13, 0x80, 0x96, 0xed, 0xfa, 0x3c, 0x29, 0xaa, 0x7c, 0x47, 0xb4, - 0x42, 0x7b, 0x36, 0xd2, 0x0f, 0xb5, 0x67, 0xb3, 0x1c, 0xd8, 0x05, 0x89, 0x1d, 0x6c, 0xa7, 0xb5, - 0xef, 0xad, 0x90, 0xf8, 0x8f, 0x64, 0x2b, 0xa4, 0x73, 0xa5, 0x94, 0xb8, 0x7d, 0x4b, 0xaa, 0xe4, - 0x61, 0x97, 0x95, 0x7c, 0x87, 0x73, 0xa0, 0xc7, 0x0e, 0x67, 0xae, 0xeb, 0x36, 0x26, 0xa7, 0x46, - 0x67, 0xc5, 0x95, 0x9b, 0xc1, 0xfe, 0xe6, 0x36, 0x7e, 0x27, 0x27, 0xf5, 0x01, 0x31, 0xb3, 0x9d, - 0x84, 0x7c, 0xbb, 0x3b, 0x89, 0xe4, 0x2b, 0x7f, 0x34, 0x0e, 0xd9, 0x65, 0xbb, 0x5e, 0xae, 0x69, - 0xce, 0x1d, 0xf2, 0xb5, 0x67, 0xbb, 0x2f, 0x53, 0xd1, 0xad, 0x9b, 0x53, 0x23, 0xcc, 0xa6, 0x3d, - 0x2c, 0xd9, 0x84, 0xd1, 0xd0, 0xcb, 0x01, 0xee, 0x59, 0xa5, 0xc3, 0xbc, 0xa3, 0x08, 0xb1, 0x92, - 0xe9, 0xaa, 0xc2, 0xe7, 0xdf, 0x68, 0xaf, 0xb3, 0x33, 0x33, 0x87, 0xba, 0x74, 0x27, 0xf7, 0xf4, - 0xbc, 0x31, 0xcb, 0x43, 0x2e, 0x3c, 0x28, 0xee, 0x88, 0xfd, 0x91, 0x04, 0x43, 0xcb, 0xb6, 0x58, - 0x45, 0xe3, 0x1f, 0xd3, 0x1d, 0x85, 0xa7, 0xdc, 0x8b, 0x24, 0xf1, 0xfe, 0xfc, 0x56, 0x5c, 0x2e, - 0xf1, 0x8c, 0x70, 0x14, 0xc6, 0x7d, 0x7a, 0xba, 0xfa, 0xff, 0x76, 0x8c, 0xe6, 0xc7, 0x22, 0xae, - 0x6b, 0xba, 0x5b, 0x54, 0xe0, 0xbf, 0xac, 0xeb, 0x25, 0xcf, 0xce, 0x89, 0xc3, 0xda, 0x79, 0x97, - 0x26, 0x88, 0x90, 0x3d, 0xdd, 0x8a, 0x71, 0xb9, 0x7d, 0x35, 0x2f, 0x1d, 0xe0, 0xa0, 0x4c, 0x68, - 0xcd, 0x2e, 0xbf, 0x2e, 0xc1, 0xf0, 0xb2, 0x5d, 0xdf, 0xd4, 0x6b, 0xff, 0xcf, 0xfb, 0xef, 0x36, - 0x1c, 0x0d, 0x68, 0x7a, 0x87, 0x4c, 0x7a, 0xe6, 0xd5, 0x04, 0xc4, 0x97, 0xed, 0x3a, 0x7a, 0x09, - 0x46, 0xc3, 0x45, 0xc3, 0xe9, 0x6e, 0x39, 0xbb, 0x7d, 0x46, 0xc8, 0x9f, 0xe9, 0x1f, 0xd7, 0xd5, - 0x64, 0x17, 0x86, 0x83, 0x33, 0xc7, 0xa9, 0x1e, 0x4c, 0x02, 0x98, 0xf9, 0xc7, 0xfa, 0xc5, 0x74, - 0x3b, 0x7b, 0x07, 0xa4, 0xdc, 0xa4, 0x77, 0x6f, 0x0f, 0x6a, 0x81, 0x94, 0x7f, 0xb8, 0x0f, 0x24, - 0x97, 0xfb, 0x4b, 0x30, 0x1a, 0x4e, 0x29, 0xbd, 0xac, 0x17, 0xc2, 0xed, 0x69, 0xbd, 0x6e, 0xa1, - 0xb5, 0x05, 0xe0, 0x8b, 0x83, 0xfb, 0x7b, 0x70, 0xf0, 0xd0, 0xf2, 0x8f, 0xf6, 0x85, 0xe6, 0x2e, - 0xae, 0x6e, 0x77, 0x31, 0xfe, 0xaf, 0x62, 0x70, 0xda, 0x5f, 0xe6, 0xbe, 0xd4, 0xc2, 0xd6, 0xbe, - 0x5b, 0xc9, 0x9a, 0x6a, 0x5d, 0xd3, 0xfd, 0xb7, 0xeb, 0x4e, 0xf8, 0xa3, 0x86, 0xe2, 0x0a, 0x79, - 0x65, 0x1d, 0x86, 0xd6, 0xd4, 0x3a, 0x56, 0xf0, 0x4b, 0x2d, 0x6c, 0x3b, 0x1d, 0x6e, 0x77, 0x1d, - 0x83, 0x01, 0x63, 0x7b, 0x5b, 0x9c, 0x35, 0x4b, 0x28, 0xfc, 0x09, 0x4d, 0x40, 0xb2, 0xa1, 0x35, - 0x35, 0x16, 0x99, 0x09, 0x85, 0x3d, 0xa0, 0x29, 0x18, 0xaa, 0x92, 0x00, 0xac, 0xb0, 0x73, 0xf3, - 0x09, 0xf1, 0xe5, 0xa5, 0x96, 0xee, 0x6c, 0x10, 0x88, 0xfc, 0x2c, 0x64, 0x58, 0x7f, 0xdc, 0xfa, - 0x27, 0x20, 0x45, 0xcf, 0x39, 0x7b, 0xbd, 0x0e, 0x92, 0xe7, 0xcb, 0xec, 0x26, 0x18, 0xe3, 0xc2, - 0x3a, 0x66, 0x0f, 0xc5, 0x62, 0x57, 0x53, 0x9e, 0x8a, 0xae, 0x08, 0x98, 0xa1, 0x5c, 0x33, 0xfe, - 0x66, 0x12, 0x8e, 0xf2, 0xf5, 0x87, 0x6a, 0x6a, 0xb3, 0x3b, 0x8e, 0x23, 0x6e, 0x2b, 0x03, 0x4f, - 0x01, 0xaa, 0xa9, 0xc9, 0xfb, 0x90, 0xb8, 0xe4, 0x38, 0x26, 0x3a, 0x0d, 0x49, 0xab, 0xd5, 0xc0, - 0xe2, 0x55, 0x8c, 0x5b, 0x4a, 0xaa, 0xa6, 0x36, 0x43, 0x10, 0x94, 0x56, 0x03, 0x2b, 0x0c, 0x05, - 0x95, 0x61, 0x6a, 0xbb, 0xd5, 0x68, 0xec, 0x57, 0x6a, 0x98, 0xfe, 0xd3, 0x3c, 0xf7, 0xdf, 0xce, - 0xe0, 0x3d, 0x53, 0xd5, 0xdd, 0x7a, 0x3f, 0xa5, 0x9c, 0xa4, 0x68, 0x25, 0x8a, 0x25, 0xfe, 0xe5, - 0x4c, 0x59, 0xe0, 0xc8, 0xbf, 0x17, 0x83, 0x94, 0x60, 0x4d, 0xaf, 0x66, 0xe1, 0x06, 0xae, 0x3a, - 0x86, 0x38, 0xca, 0xe0, 0x3e, 0x23, 0x04, 0xf1, 0x3a, 0x1f, 0xa2, 0xf4, 0xa5, 0x23, 0x0a, 0x79, - 0x20, 0x30, 0xf7, 0xc2, 0x1c, 0x81, 0x99, 0x2d, 0x32, 0x6a, 0x09, 0xd3, 0x10, 0x7b, 0xa6, 0x97, - 0x8e, 0x28, 0xf4, 0x09, 0xe5, 0x60, 0x80, 0xb8, 0xac, 0xc3, 0xbe, 0x08, 0x4c, 0xe0, 0xfc, 0x19, - 0x1d, 0x83, 0xa4, 0xa9, 0x3a, 0x55, 0x76, 0xd6, 0x9d, 0x34, 0xb0, 0x47, 0x92, 0x98, 0xd9, 0x97, - 0x18, 0xc2, 0xff, 0x91, 0x8a, 0x18, 0x83, 0x7d, 0xf2, 0x92, 0xc8, 0xbd, 0xa6, 0x3a, 0x0e, 0xb6, - 0x74, 0xc2, 0x90, 0xa1, 0x23, 0x04, 0x89, 0x2d, 0xa3, 0xb6, 0xcf, 0xff, 0x4b, 0x16, 0xfd, 0xcd, - 0xff, 0x2d, 0x0f, 0xf5, 0x87, 0x0a, 0x6d, 0x64, 0xff, 0x1c, 0x30, 0x23, 0x80, 0x45, 0x82, 0x54, - 0x86, 0x71, 0xb5, 0x56, 0xd3, 0xd8, 0x3f, 0xac, 0xaa, 0x6c, 0x69, 0x74, 0x3d, 0x6c, 0xd3, 0x7f, - 0xfd, 0xd8, 0x6d, 0x2c, 0x90, 0x47, 0x50, 0xe4, 0xf8, 0xc5, 0x34, 0x0c, 0x9a, 0x4c, 0x28, 0xf9, - 0x02, 0x8c, 0xb5, 0x49, 0x4a, 0xe4, 0xdb, 0xd5, 0xf4, 0x9a, 0xb8, 0x45, 0x48, 0x7e, 0x13, 0x18, - 0xfd, 0x6c, 0x2d, 0x3b, 0x24, 0x42, 0x7f, 0x17, 0xdf, 0xd3, 0xfd, 0x8e, 0xe9, 0x88, 0xef, 0x8e, - 0xa9, 0x6a, 0x6a, 0xc5, 0x34, 0xe5, 0xcf, 0xaf, 0x96, 0xce, 0xf1, 0x06, 0x76, 0xad, 0x74, 0xc6, - 0xb0, 0xea, 0xb3, 0x75, 0xac, 0x8b, 0xf5, 0x2d, 0x69, 0x52, 0x4d, 0xcd, 0xa6, 0xee, 0xe8, 0x7d, - 0x46, 0xd7, 0xbe, 0xe0, 0xfb, 0x4d, 0x6f, 0x9c, 0x26, 0x16, 0xe6, 0xd6, 0x16, 0x5d, 0x3f, 0xfe, - 0x4a, 0x0c, 0x4e, 0xfa, 0xfc, 0xd8, 0x87, 0xdc, 0xee, 0xce, 0xf9, 0xce, 0x1e, 0xdf, 0xc7, 0x25, - 0xf4, 0xcb, 0x90, 0x20, 0xf8, 0x28, 0xe2, 0x9f, 0xe6, 0xe4, 0x7e, 0xf5, 0xeb, 0xff, 0x4c, 0x0e, - 0x2e, 0xb6, 0x02, 0xa3, 0x42, 0x99, 0x14, 0xdf, 0xdf, 0xbf, 0xfd, 0xb2, 0xde, 0x17, 0x84, 0xed, - 0xdb, 0x67, 0xc6, 0xb0, 0x0d, 0xbf, 0x7d, 0x16, 0xe4, 0x2e, 0x3b, 0x03, 0x2c, 0x63, 0xf6, 0xde, - 0xe2, 0x38, 0x40, 0x3a, 0xee, 0x76, 0x31, 0xaf, 0xd7, 0x08, 0xf6, 0xb9, 0x6b, 0xb1, 0x07, 0xc7, - 0x9e, 0x27, 0x7d, 0x7b, 0xfb, 0xd7, 0x22, 0xb1, 0x1f, 0x73, 0x8f, 0xd9, 0x48, 0xfc, 0x3f, 0x6f, - 0x8a, 0x23, 0x34, 0xe0, 0xc9, 0xc7, 0xf7, 0x20, 0x1e, 0x98, 0xe9, 0x3a, 0x5f, 0xcc, 0xf8, 0x26, - 0x0b, 0xc5, 0x47, 0x29, 0xff, 0xb2, 0x04, 0xc7, 0xdb, 0xba, 0xe6, 0x39, 0x7e, 0xa1, 0xc3, 0x1d, - 0xc2, 0xbe, 0x4f, 0xf7, 0xf9, 0xef, 0x13, 0x2e, 0x74, 0x10, 0xf6, 0xc1, 0x48, 0x61, 0x99, 0x14, - 0x01, 0x69, 0x9f, 0x81, 0xa3, 0x41, 0x61, 0x85, 0x99, 0xee, 0x87, 0x91, 0x60, 0x61, 0xca, 0xcd, - 0x35, 0x1c, 0x28, 0x4d, 0xe5, 0x4a, 0xd8, 0xce, 0xae, 0xae, 0x65, 0x48, 0xbb, 0xa8, 0xbc, 0x9e, - 0xec, 0x5b, 0x55, 0x8f, 0x52, 0xfe, 0x88, 0x04, 0xd3, 0xc1, 0x1e, 0xbc, 0x15, 0xaa, 0x7d, 0x30, - 0x61, 0x6f, 0xdb, 0x10, 0xbf, 0x2e, 0xc1, 0x3d, 0x3d, 0x64, 0xe2, 0x06, 0x78, 0x19, 0x26, 0x7c, - 0x5b, 0xf4, 0x22, 0x85, 0x8b, 0x61, 0x3f, 0x1d, 0xfd, 0x6e, 0xc1, 0x2d, 0x9a, 0xee, 0x22, 0x46, - 0xf9, 0xdc, 0x1f, 0x4c, 0x8d, 0xb7, 0xb7, 0xd9, 0xca, 0x78, 0xfb, 0xb6, 0xfa, 0x6d, 0xf4, 0x8f, - 0x57, 0x25, 0x78, 0x28, 0xa8, 0x6a, 0x87, 0xf7, 0xe6, 0x6f, 0xd4, 0x38, 0xfc, 0x47, 0x09, 0x4e, - 0xf7, 0x23, 0x9c, 0x5b, 0xdf, 0x8e, 0x7b, 0x2f, 0xca, 0xc2, 0xe3, 0xf1, 0xf0, 0x01, 0x4e, 0x18, - 0x70, 0x2f, 0x45, 0x2e, 0xb7, 0x3b, 0x60, 0x78, 0x93, 0x07, 0x96, 0x7f, 0xc8, 0x5d, 0x23, 0x07, - 0x57, 0x9f, 0xc2, 0xc8, 0x81, 0xf5, 0x67, 0x87, 0xb1, 0x88, 0x75, 0x18, 0x0b, 0xdf, 0xfa, 0xf0, - 0x2a, 0xcf, 0x5b, 0x1d, 0x5e, 0x8e, 0xbd, 0x1d, 0xc6, 0x3b, 0xb8, 0x32, 0x8f, 0xea, 0x03, 0x78, - 0xb2, 0x82, 0xda, 0x9d, 0x55, 0xde, 0x87, 0x29, 0xda, 0x6f, 0x07, 0x43, 0xdf, 0x69, 0x95, 0x9b, - 0x3c, 0xb7, 0x74, 0xec, 0x9a, 0xeb, 0xbe, 0x08, 0x03, 0x6c, 0x9c, 0xb9, 0xba, 0x87, 0x70, 0x14, - 0xce, 0x40, 0xfe, 0x79, 0x91, 0xcb, 0x4a, 0x42, 0xec, 0xce, 0x31, 0xd4, 0x8f, 0xae, 0xb7, 0x29, - 0x86, 0x7c, 0xc6, 0xf8, 0xa6, 0xc8, 0x6a, 0x9d, 0xa5, 0xe3, 0xe6, 0xa8, 0xde, 0xb6, 0xac, 0xc6, - 0x6c, 0x73, 0x67, 0xd3, 0xd7, 0x2f, 0x8a, 0xf4, 0xe5, 0xea, 0x14, 0x91, 0xbe, 0xde, 0x18, 0xd3, - 0xbb, 0x89, 0x2c, 0x42, 0xcc, 0xbf, 0x88, 0x89, 0xec, 0x7b, 0x12, 0x9c, 0xa0, 0xba, 0xf9, 0xdf, - 0xb8, 0x1e, 0xd4, 0xe4, 0x8f, 0x00, 0xb2, 0xad, 0x6a, 0xa5, 0x63, 0x74, 0x67, 0x6d, 0xab, 0x7a, - 0x25, 0x30, 0xbf, 0x3c, 0x02, 0xa8, 0x66, 0x3b, 0x61, 0x6c, 0x76, 0x7c, 0x3d, 0x5b, 0xb3, 0x9d, - 0x2b, 0x3d, 0x66, 0xa3, 0xc4, 0x6d, 0x18, 0xce, 0x6f, 0x48, 0x90, 0xef, 0xa4, 0x32, 0x1f, 0x3e, - 0x0d, 0x8e, 0x05, 0xde, 0xde, 0x87, 0x47, 0xf0, 0x91, 0x7e, 0xde, 0x59, 0x87, 0xc2, 0xe8, 0xa8, - 0x85, 0xef, 0x74, 0x1d, 0x30, 0x15, 0xf4, 0xd0, 0xf6, 0xca, 0xfa, 0x0d, 0x0b, 0x9f, 0x2f, 0xb6, - 0xe5, 0xd5, 0xbf, 0x10, 0xb5, 0xf7, 0x1e, 0x4c, 0x76, 0x91, 0xfa, 0x4e, 0xcf, 0x7b, 0x3b, 0x5d, - 0x07, 0xf3, 0x76, 0x97, 0xef, 0x4f, 0xf2, 0x48, 0x08, 0x5e, 0x8d, 0xf2, 0xad, 0xc5, 0x3a, 0xdd, - 0xad, 0x96, 0xdf, 0x0a, 0x77, 0x75, 0xa4, 0xe2, 0xb2, 0x15, 0x20, 0xb1, 0xa3, 0xd9, 0x0e, 0x17, - 0xeb, 0x81, 0x6e, 0x62, 0x85, 0xa8, 0x29, 0x8d, 0x8c, 0x20, 0x4b, 0x59, 0xaf, 0x19, 0x46, 0x83, - 0x8b, 0x21, 0x5f, 0x86, 0x31, 0x1f, 0x8c, 0x77, 0x72, 0x0e, 0x12, 0xa6, 0xc1, 0xbf, 0x0b, 0x34, - 0x74, 0xe6, 0x64, 0xb7, 0x4e, 0x08, 0x0d, 0x57, 0x9b, 0xe2, 0xcb, 0x13, 0x80, 0x18, 0x33, 0x7a, - 0xb8, 0x4b, 0x74, 0xb1, 0x0e, 0xe3, 0x01, 0x28, 0xef, 0xe4, 0x4d, 0x30, 0x60, 0x52, 0x88, 0x7b, - 0x09, 0xb6, 0x5b, 0x37, 0x14, 0xcb, 0xfd, 0x12, 0x0b, 0x7d, 0x3a, 0xf3, 0x9d, 0xa3, 0x90, 0xa4, - 0x5c, 0xd1, 0xc7, 0x25, 0x00, 0xdf, 0x51, 0xad, 0x99, 0x6e, 0x6c, 0x3a, 0xaf, 0x89, 0xf3, 0xb3, - 0x7d, 0xe3, 0xf3, 0x9a, 0xed, 0xf4, 0x7b, 0xfe, 0xdd, 0xb7, 0x3f, 0x1a, 0xbb, 0x0f, 0xc9, 0xb3, - 0x5d, 0x56, 0xe3, 0xbe, 0x78, 0xf9, 0x6c, 0xe0, 0xa3, 0x34, 0x8f, 0xf6, 0xd7, 0x95, 0x90, 0x6c, - 0xa6, 0x5f, 0x74, 0x2e, 0xd8, 0x05, 0x2a, 0xd8, 0x59, 0xf4, 0x44, 0xb4, 0x60, 0xb3, 0xef, 0x0c, - 0x06, 0xcd, 0xbb, 0xd1, 0xef, 0x48, 0x30, 0xd1, 0x69, 0x49, 0x87, 0xce, 0xf7, 0x27, 0x45, 0x7b, - 0x49, 0x91, 0x7f, 0xfa, 0x10, 0x94, 0x5c, 0x95, 0x05, 0xaa, 0xca, 0x1c, 0x7a, 0xf6, 0x10, 0xaa, - 0xcc, 0xfa, 0xe6, 0x1d, 0xf4, 0xbf, 0x25, 0xb8, 0xbb, 0xe7, 0x0a, 0x09, 0xcd, 0xf5, 0x27, 0x65, - 0x8f, 0xda, 0x29, 0x5f, 0xfc, 0x61, 0x58, 0x70, 0x8d, 0x9f, 0xa7, 0x1a, 0x5f, 0x46, 0x8b, 0x87, - 0xd1, 0xd8, 0xab, 0x88, 0xfc, 0xba, 0xff, 0x56, 0xf0, 0xc8, 0x7f, 0x6f, 0x77, 0x6a, 0x5b, 0x78, - 0x44, 0x04, 0x46, 0x7b, 0x51, 0x2b, 0xbf, 0x85, 0xaa, 0xa0, 0xa0, 0xb5, 0x1f, 0x72, 0xd0, 0x66, - 0xdf, 0x19, 0x4c, 0xfc, 0xef, 0x46, 0xff, 0x4b, 0xea, 0x7c, 0x82, 0xff, 0xa9, 0x9e, 0x22, 0x76, - 0x5f, 0x54, 0xe5, 0xcf, 0x1f, 0x9c, 0x90, 0x2b, 0xd9, 0xa4, 0x4a, 0xd6, 0x11, 0xbe, 0xdd, 0x4a, - 0x76, 0x1c, 0x44, 0xf4, 0x35, 0x09, 0x26, 0x3a, 0xad, 0x49, 0x22, 0xc2, 0xb2, 0xc7, 0x22, 0x2b, - 0x22, 0x2c, 0x7b, 0x2d, 0x80, 0xe4, 0x37, 0x51, 0xe5, 0xcf, 0xa1, 0x27, 0xbb, 0x29, 0xdf, 0x73, - 0x14, 0x49, 0x2c, 0xf6, 0x2c, 0xf2, 0x23, 0x62, 0xb1, 0x9f, 0x75, 0x4c, 0x44, 0x2c, 0xf6, 0xb5, - 0xc6, 0x88, 0x8e, 0x45, 0x57, 0xb3, 0x3e, 0x87, 0xd1, 0x46, 0x5f, 0x91, 0x60, 0x38, 0x50, 0x11, - 0xa3, 0xc7, 0x7b, 0x0a, 0xda, 0x69, 0xc1, 0xd0, 0xfd, 0xc5, 0x66, 0xf7, 0x82, 0x5b, 0x5e, 0xa4, - 0xba, 0xcc, 0xa3, 0xb9, 0xc3, 0xe8, 0x62, 0x05, 0x24, 0xfe, 0x86, 0x04, 0xe3, 0x1d, 0xaa, 0xcc, - 0x88, 0x28, 0xec, 0x5e, 0x34, 0xe7, 0xcf, 0x1f, 0x9c, 0x90, 0x6b, 0x75, 0x91, 0x6a, 0xf5, 0x13, - 0xe8, 0x99, 0xc3, 0x68, 0xe5, 0x9b, 0x9f, 0x6f, 0x7a, 0x07, 0xa2, 0x7d, 0xfd, 0xa0, 0x73, 0x07, - 0x14, 0x4c, 0x28, 0xf4, 0xd4, 0x81, 0xe9, 0xb8, 0x3e, 0x2f, 0x50, 0x7d, 0x9e, 0x47, 0xab, 0x3f, - 0x9c, 0x3e, 0xed, 0xd3, 0xfa, 0x17, 0xda, 0xaf, 0xe6, 0xf7, 0xf6, 0xa2, 0x8e, 0xc5, 0x6a, 0xfe, - 0x89, 0x03, 0xd1, 0x70, 0xa5, 0xce, 0x53, 0xa5, 0xce, 0xa0, 0xc7, 0xba, 0x29, 0xe5, 0x3b, 0xf5, - 0xae, 0xe9, 0xdb, 0xc6, 0xec, 0x3b, 0x59, 0x09, 0xfc, 0x6e, 0xf4, 0x53, 0xe2, 0xc4, 0xf1, 0xa9, - 0x9e, 0xfd, 0xfa, 0xea, 0xd8, 0xfc, 0x43, 0x7d, 0x60, 0x72, 0xb9, 0xee, 0xa3, 0x72, 0x4d, 0xa2, - 0x93, 0xdd, 0xe4, 0x22, 0xb5, 0x2c, 0xfa, 0xa0, 0xe4, 0x5e, 0x52, 0x38, 0xdd, 0x9b, 0xb7, 0xbf, - 0xd8, 0xed, 0x7e, 0xd0, 0xa1, 0x43, 0x09, 0x2c, 0x3f, 0x40, 0x25, 0x99, 0x46, 0x93, 0x5d, 0x25, - 0x61, 0xa5, 0xef, 0xed, 0x3e, 0x39, 0xf0, 0x27, 0x83, 0x5d, 0x3f, 0x5e, 0x51, 0xc7, 0x3a, 0xb6, - 0x35, 0xfb, 0x50, 0x1f, 0xaf, 0xe8, 0xef, 0xf5, 0xd4, 0xef, 0x24, 0x21, 0xb3, 0xc0, 0x7a, 0x59, - 0x77, 0x54, 0xe7, 0x87, 0x5c, 0x08, 0x20, 0x9b, 0x7f, 0x93, 0x8d, 0x7d, 0x2a, 0xd2, 0xfb, 0xf8, - 0x61, 0xe6, 0x40, 0xd7, 0xb6, 0xd9, 0x21, 0x41, 0x7e, 0x43, 0x3a, 0xcc, 0x4f, 0x66, 0x9f, 0x77, - 0xa3, 0x67, 0x17, 0xd8, 0x47, 0x1e, 0xdf, 0x27, 0xc1, 0x51, 0x8a, 0xe5, 0xc5, 0x1b, 0xc5, 0x14, - 0x77, 0xf6, 0xba, 0x7a, 0xcc, 0x92, 0xea, 0xdb, 0x82, 0x61, 0x9f, 0x65, 0xbc, 0x8f, 0xdf, 0x67, - 0x39, 0xe9, 0xeb, 0x3c, 0xcc, 0x56, 0x56, 0xc6, 0x1b, 0x6d, 0x94, 0x76, 0x68, 0x5d, 0x9f, 0x38, - 0xfc, 0xba, 0xfe, 0x39, 0x18, 0xf2, 0x65, 0xfa, 0x5c, 0x32, 0xe2, 0x9a, 0x69, 0x78, 0x13, 0xcd, - 0x4f, 0x8c, 0xde, 0x2f, 0xc1, 0xd1, 0x8e, 0x93, 0x20, 0xfd, 0x5f, 0xb4, 0x07, 0xdc, 0xa4, 0x0b, - 0x19, 0xa7, 0x23, 0x5f, 0x59, 0x99, 0x68, 0x75, 0xaa, 0x26, 0xd6, 0x60, 0x38, 0x30, 0x81, 0xe5, - 0xc4, 0x7f, 0x94, 0xee, 0xff, 0x86, 0x45, 0x90, 0x01, 0xca, 0x43, 0x0a, 0xef, 0x99, 0x86, 0xe5, - 0xe0, 0x1a, 0x3d, 0xf2, 0x90, 0x52, 0xdc, 0x67, 0x79, 0x05, 0x50, 0xfb, 0xe0, 0x86, 0xbf, 0x43, - 0x9a, 0xf6, 0xbe, 0x43, 0x3a, 0x01, 0x49, 0xff, 0x97, 0x3a, 0xd9, 0x83, 0xb7, 0x4f, 0x71, 0xbb, - 0x63, 0xfe, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x5a, 0x69, 0x9a, 0x3e, 0x4a, 0x94, 0x00, 0x00, + 0x41, 0x1b, 0x5b, 0x57, 0xb5, 0x2a, 0xce, 0x0d, 0x50, 0x06, 0x0f, 0xb6, 0x31, 0x58, 0x67, 0xcf, + 0xc3, 0x3c, 0x04, 0x1d, 0x9a, 0x87, 0x34, 0xde, 0x73, 0xb0, 0x6e, 0x6b, 0x86, 0x9e, 0x1b, 0xa4, + 0x4c, 0xee, 0xef, 0x30, 0x8a, 0xb8, 0x51, 0x0b, 0xb3, 0xf0, 0xe8, 0xd0, 0x39, 0x18, 0x34, 0x4c, + 0x47, 0x33, 0x74, 0x3b, 0x97, 0x9a, 0x96, 0x4e, 0x0d, 0x9d, 0x39, 0xd9, 0xd1, 0x11, 0x56, 0x19, + 0x8e, 0x22, 0x90, 0xd1, 0x22, 0x64, 0x6d, 0xa3, 0x65, 0x55, 0x71, 0xa5, 0x6a, 0xd4, 0x70, 0x45, + 0xd3, 0xb7, 0x8d, 0x5c, 0x9a, 0x32, 0x98, 0x6a, 0x57, 0x84, 0x22, 0xce, 0x1b, 0x35, 0xbc, 0xa8, + 0x6f, 0x1b, 0xca, 0x88, 0x1d, 0x68, 0xa3, 0x63, 0x30, 0x60, 0xef, 0xeb, 0x8e, 0xba, 0x97, 0xcb, + 0x50, 0x0f, 0xe1, 0x2d, 0xf9, 0x37, 0x06, 0x60, 0xb4, 0x1f, 0x17, 0xbb, 0x00, 0xc9, 0x6d, 0xa2, + 0x65, 0x2e, 0x76, 0x10, 0x1b, 0x30, 0x9a, 0xa0, 0x11, 0x07, 0x0e, 0x69, 0xc4, 0x39, 0x18, 0xd2, + 0xb1, 0xed, 0xe0, 0x1a, 0xf3, 0x88, 0x78, 0x9f, 0x3e, 0x05, 0x8c, 0xa8, 0xdd, 0xa5, 0x12, 0x87, + 0x72, 0xa9, 0xb7, 0xc0, 0xa8, 0x2b, 0x52, 0xc5, 0x52, 0xf5, 0xba, 0xf0, 0xcd, 0xd9, 0x28, 0x49, + 0x66, 0xca, 0x82, 0x4e, 0x21, 0x64, 0xca, 0x08, 0x0e, 0xb4, 0x51, 0x09, 0xc0, 0xd0, 0xb1, 0xb1, + 0x5d, 0xa9, 0xe1, 0x6a, 0x23, 0x97, 0xea, 0x62, 0xa5, 0x55, 0x82, 0xd2, 0x66, 0x25, 0x83, 0x41, + 0xab, 0x0d, 0xf4, 0xb4, 0xe7, 0x6a, 0x83, 0x5d, 0x3c, 0x65, 0x99, 0x4d, 0xb2, 0x36, 0x6f, 0xdb, + 0x84, 0x11, 0x0b, 0x13, 0xbf, 0xc7, 0x35, 0xae, 0x59, 0x9a, 0x0a, 0x31, 0x13, 0xa9, 0x99, 0xc2, + 0xc9, 0x98, 0x62, 0xc3, 0x96, 0xbf, 0x89, 0xee, 0x05, 0x17, 0x50, 0xa1, 0x6e, 0x05, 0x34, 0x0a, + 0x65, 0x04, 0x70, 0x45, 0x6d, 0xe2, 0xfc, 0xcb, 0x30, 0x12, 0x34, 0x0f, 0x9a, 0x80, 0xa4, 0xed, + 0xa8, 0x96, 0x43, 0xbd, 0x30, 0xa9, 0xb0, 0x06, 0xca, 0x42, 0x1c, 0xeb, 0x35, 0x1a, 0xe5, 0x92, + 0x0a, 0xf9, 0x89, 0x7e, 0xc2, 0x53, 0x38, 0x4e, 0x15, 0x7e, 0xa0, 0x7d, 0x44, 0x03, 0x9c, 0xc3, + 0x7a, 0xe7, 0x9f, 0x82, 0xe1, 0x80, 0x02, 0xfd, 0x76, 0x2d, 0xbf, 0x0b, 0x8e, 0x76, 0x64, 0x8d, + 0xde, 0x02, 0x13, 0x2d, 0x5d, 0xd3, 0x1d, 0x6c, 0x99, 0x16, 0x26, 0x1e, 0xcb, 0xba, 0xca, 0xfd, + 0x97, 0xc1, 0x2e, 0x3e, 0xb7, 0xe9, 0xc7, 0x66, 0x5c, 0x94, 0xf1, 0x56, 0x3b, 0xf0, 0x74, 0x3a, + 0xf5, 0xfa, 0x60, 0xf6, 0x95, 0x57, 0x5e, 0x79, 0x25, 0x26, 0x7f, 0x6c, 0x00, 0x26, 0x3a, 0xcd, + 0x99, 0x8e, 0xd3, 0xf7, 0x18, 0x0c, 0xe8, 0xad, 0xe6, 0x16, 0xb6, 0xa8, 0x91, 0x92, 0x0a, 0x6f, + 0xa1, 0x39, 0x48, 0x36, 0xd4, 0x2d, 0xdc, 0xc8, 0x25, 0xa6, 0xa5, 0x53, 0x23, 0x67, 0x1e, 0xee, + 0x6b, 0x56, 0xce, 0x2c, 0x11, 0x12, 0x85, 0x51, 0xa2, 0x67, 0x20, 0xc1, 0x43, 0x34, 0xe1, 0x70, + 0xba, 0x3f, 0x0e, 0x64, 0x2e, 0x29, 0x94, 0x0e, 0xdd, 0x05, 0x69, 0xf2, 0x97, 0xf9, 0xc6, 0x00, + 0x95, 0x39, 0x45, 0x00, 0xc4, 0x2f, 0x50, 0x1e, 0x52, 0x74, 0x9a, 0xd4, 0xb0, 0x58, 0xda, 0xdc, + 0x36, 0x71, 0xac, 0x1a, 0xde, 0x56, 0x5b, 0x0d, 0xa7, 0x72, 0x55, 0x6d, 0xb4, 0x30, 0x75, 0xf8, + 0xb4, 0x92, 0xe1, 0xc0, 0x2b, 0x04, 0x86, 0xa6, 0x60, 0x88, 0xcd, 0x2a, 0x4d, 0xaf, 0xe1, 0x3d, + 0x1a, 0x3d, 0x93, 0x0a, 0x9b, 0x68, 0x8b, 0x04, 0x42, 0xba, 0x7f, 0xd1, 0x36, 0x74, 0xe1, 0x9a, + 0xb4, 0x0b, 0x02, 0xa0, 0xdd, 0x3f, 0x15, 0x0e, 0xdc, 0x77, 0x77, 0x56, 0x2f, 0xec, 0x53, 0xf2, + 0x97, 0x63, 0x90, 0xa0, 0xf1, 0x62, 0x14, 0x86, 0x36, 0xde, 0xba, 0x56, 0xae, 0x94, 0x56, 0x37, + 0x8b, 0x4b, 0xe5, 0xac, 0x84, 0x46, 0x00, 0x28, 0xe0, 0xe2, 0xd2, 0xea, 0xdc, 0x46, 0x36, 0xe6, + 0xb6, 0x17, 0x57, 0x36, 0xce, 0x3d, 0x99, 0x8d, 0xbb, 0x04, 0x9b, 0x0c, 0x90, 0xf0, 0x23, 0x3c, + 0x71, 0x26, 0x9b, 0x44, 0x59, 0xc8, 0x30, 0x06, 0x8b, 0x6f, 0x29, 0x97, 0xce, 0x3d, 0x99, 0x1d, + 0x08, 0x42, 0x9e, 0x38, 0x93, 0x1d, 0x44, 0xc3, 0x90, 0xa6, 0x90, 0xe2, 0xea, 0xea, 0x52, 0x36, + 0xe5, 0xf2, 0x5c, 0xdf, 0x50, 0x16, 0x57, 0x16, 0xb2, 0x69, 0x97, 0xe7, 0x82, 0xb2, 0xba, 0xb9, + 0x96, 0x05, 0x97, 0xc3, 0x72, 0x79, 0x7d, 0x7d, 0x6e, 0xa1, 0x9c, 0x1d, 0x72, 0x31, 0x8a, 0x6f, + 0xdd, 0x28, 0xaf, 0x67, 0x33, 0x01, 0xb1, 0x9e, 0x38, 0x93, 0x1d, 0x76, 0xbb, 0x28, 0xaf, 0x6c, + 0x2e, 0x67, 0x47, 0xd0, 0x18, 0x0c, 0xb3, 0x2e, 0x84, 0x10, 0xa3, 0x21, 0xd0, 0xb9, 0x27, 0xb3, + 0x59, 0x4f, 0x10, 0xc6, 0x65, 0x2c, 0x00, 0x38, 0xf7, 0x64, 0x16, 0xc9, 0xf3, 0x90, 0xa4, 0xde, + 0x85, 0x10, 0x8c, 0x2c, 0xcd, 0x15, 0xcb, 0x4b, 0x95, 0xd5, 0xb5, 0x8d, 0xc5, 0xd5, 0x95, 0xb9, + 0xa5, 0xac, 0xe4, 0xc1, 0x94, 0xf2, 0xf3, 0x9b, 0x8b, 0x4a, 0xb9, 0x94, 0x8d, 0xf9, 0x61, 0x6b, + 0xe5, 0xb9, 0x8d, 0x72, 0x29, 0x1b, 0x97, 0xab, 0x30, 0xd1, 0x29, 0x4e, 0x76, 0x9c, 0x19, 0xbe, + 0x21, 0x8e, 0x75, 0x19, 0x62, 0xca, 0xab, 0x6d, 0x88, 0xbf, 0x15, 0x83, 0xf1, 0x0e, 0x6b, 0x45, + 0xc7, 0x4e, 0x9e, 0x85, 0x24, 0x73, 0x51, 0xb6, 0x7a, 0x3e, 0xd4, 0x71, 0xd1, 0xa1, 0x0e, 0xdb, + 0xb6, 0x82, 0x52, 0x3a, 0x7f, 0x06, 0x11, 0xef, 0x92, 0x41, 0x10, 0x16, 0x6d, 0x31, 0xfd, 0x27, + 0xdb, 0x62, 0x3a, 0x5b, 0xf6, 0xce, 0xf5, 0xb3, 0xec, 0x51, 0xd8, 0xc1, 0x62, 0x7b, 0xb2, 0x43, + 0x6c, 0xbf, 0x00, 0x63, 0x6d, 0x8c, 0xfa, 0x8e, 0xb1, 0xef, 0x95, 0x20, 0xd7, 0xcd, 0x38, 0x11, + 0x91, 0x2e, 0x16, 0x88, 0x74, 0x17, 0xc2, 0x16, 0xbc, 0xa7, 0xfb, 0x20, 0xb4, 0x8d, 0xf5, 0xe7, + 0x24, 0x38, 0xd6, 0x39, 0x53, 0xec, 0x28, 0xc3, 0x33, 0x30, 0xd0, 0xc4, 0xce, 0x8e, 0x21, 0xb2, + 0xa5, 0x07, 0x3a, 0xac, 0xc1, 0xe4, 0x71, 0x78, 0xb0, 0x39, 0x95, 0x7f, 0x11, 0x8f, 0x77, 0x4b, + 0xf7, 0x98, 0x34, 0x6d, 0x92, 0x7e, 0x30, 0x06, 0x47, 0x3b, 0x32, 0xef, 0x28, 0xe8, 0xdd, 0x00, + 0x9a, 0x6e, 0xb6, 0x1c, 0x96, 0x11, 0xb1, 0x00, 0x9b, 0xa6, 0x10, 0x1a, 0xbc, 0x48, 0xf0, 0x6c, + 0x39, 0xee, 0xf3, 0x38, 0x7d, 0x0e, 0x0c, 0x44, 0x11, 0xce, 0x7b, 0x82, 0x26, 0xa8, 0xa0, 0x93, + 0x5d, 0x34, 0x6d, 0x73, 0xcc, 0xc7, 0x20, 0x5b, 0x6d, 0x68, 0x58, 0x77, 0x2a, 0xb6, 0x63, 0x61, + 0xb5, 0xa9, 0xe9, 0x75, 0xba, 0x82, 0xa4, 0x0a, 0xc9, 0x6d, 0xb5, 0x61, 0x63, 0x65, 0x94, 0x3d, + 0x5e, 0x17, 0x4f, 0x09, 0x05, 0x75, 0x20, 0xcb, 0x47, 0x31, 0x10, 0xa0, 0x60, 0x8f, 0x5d, 0x0a, + 0xf9, 0x67, 0xd3, 0x30, 0xe4, 0xcb, 0xab, 0xd1, 0x3d, 0x90, 0x79, 0x51, 0xbd, 0xaa, 0x56, 0xc4, + 0x5e, 0x89, 0x59, 0x62, 0x88, 0xc0, 0xd6, 0xf8, 0x7e, 0xe9, 0x31, 0x98, 0xa0, 0x28, 0x46, 0xcb, + 0xc1, 0x56, 0xa5, 0xda, 0x50, 0x6d, 0x9b, 0x1a, 0x2d, 0x45, 0x51, 0x11, 0x79, 0xb6, 0x4a, 0x1e, + 0xcd, 0x8b, 0x27, 0xe8, 0x2c, 0x8c, 0x53, 0x8a, 0x66, 0xab, 0xe1, 0x68, 0x66, 0x03, 0x57, 0xc8, + 0xee, 0xcd, 0xa6, 0x2b, 0x89, 0x2b, 0xd9, 0x18, 0xc1, 0x58, 0xe6, 0x08, 0x44, 0x22, 0x1b, 0x95, + 0xe0, 0x6e, 0x4a, 0x56, 0xc7, 0x3a, 0xb6, 0x54, 0x07, 0x57, 0xf0, 0x4b, 0x2d, 0xb5, 0x61, 0x57, + 0x54, 0xbd, 0x56, 0xd9, 0x51, 0xed, 0x9d, 0xdc, 0x04, 0x61, 0x50, 0x8c, 0xe5, 0x24, 0xe5, 0x04, + 0x41, 0x5c, 0xe0, 0x78, 0x65, 0x8a, 0x36, 0xa7, 0xd7, 0x2e, 0xa9, 0xf6, 0x0e, 0x2a, 0xc0, 0x31, + 0xca, 0xc5, 0x76, 0x2c, 0x4d, 0xaf, 0x57, 0xaa, 0x3b, 0xb8, 0xba, 0x5b, 0x69, 0x39, 0xdb, 0xe7, + 0x73, 0x77, 0xf9, 0xfb, 0xa7, 0x12, 0xae, 0x53, 0x9c, 0x79, 0x82, 0xb2, 0xe9, 0x6c, 0x9f, 0x47, + 0xeb, 0x90, 0x21, 0x83, 0xd1, 0xd4, 0x5e, 0xc6, 0x95, 0x6d, 0xc3, 0xa2, 0x4b, 0xe3, 0x48, 0x87, + 0xd0, 0xe4, 0xb3, 0xe0, 0xcc, 0x2a, 0x27, 0x58, 0x36, 0x6a, 0xb8, 0x90, 0x5c, 0x5f, 0x2b, 0x97, + 0x4b, 0xca, 0x90, 0xe0, 0x72, 0xd1, 0xb0, 0x88, 0x43, 0xd5, 0x0d, 0xd7, 0xc0, 0x43, 0xcc, 0xa1, + 0xea, 0x86, 0x30, 0xef, 0x59, 0x18, 0xaf, 0x56, 0x99, 0xce, 0x5a, 0xb5, 0xc2, 0xf7, 0x58, 0x76, + 0x2e, 0x1b, 0x30, 0x56, 0xb5, 0xba, 0xc0, 0x10, 0xb8, 0x8f, 0xdb, 0xe8, 0x69, 0x38, 0xea, 0x19, + 0xcb, 0x4f, 0x38, 0xd6, 0xa6, 0x65, 0x98, 0xf4, 0x2c, 0x8c, 0x9b, 0xfb, 0xed, 0x84, 0x28, 0xd0, + 0xa3, 0xb9, 0x1f, 0x26, 0x7b, 0x0a, 0x26, 0xcc, 0x1d, 0xb3, 0x9d, 0xee, 0xb4, 0x9f, 0x0e, 0x99, + 0x3b, 0x66, 0x98, 0xf0, 0x7e, 0xba, 0xe1, 0xb6, 0x70, 0x55, 0x75, 0x70, 0x2d, 0x77, 0xdc, 0x8f, + 0xee, 0x7b, 0x80, 0x66, 0x21, 0x5b, 0xad, 0x56, 0xb0, 0xae, 0x6e, 0x35, 0x70, 0x45, 0xb5, 0xb0, + 0xae, 0xda, 0xb9, 0x29, 0x3f, 0xf2, 0x48, 0xb5, 0x5a, 0xa6, 0x4f, 0xe7, 0xe8, 0x43, 0x74, 0x1a, + 0xc6, 0x8c, 0xad, 0x17, 0xab, 0xcc, 0x25, 0x2b, 0xa6, 0x85, 0xb7, 0xb5, 0xbd, 0xdc, 0x7d, 0xd4, + 0xbe, 0xa3, 0xe4, 0x01, 0x75, 0xc8, 0x35, 0x0a, 0x46, 0x0f, 0x41, 0xb6, 0x6a, 0xef, 0xa8, 0x96, + 0x49, 0x63, 0xb2, 0x6d, 0xaa, 0x55, 0x9c, 0xbb, 0x9f, 0xa1, 0x32, 0xf8, 0x8a, 0x00, 0x93, 0x29, + 0x61, 0x5f, 0xd3, 0xb6, 0x1d, 0xc1, 0xf1, 0x41, 0x36, 0x25, 0x28, 0x8c, 0x73, 0x3b, 0x05, 0x59, + 0x62, 0x8a, 0x40, 0xc7, 0xa7, 0x28, 0xda, 0x88, 0xb9, 0x63, 0xfa, 0xfb, 0xbd, 0x17, 0x86, 0x09, + 0xa6, 0xd7, 0xe9, 0x43, 0x2c, 0x21, 0x33, 0x77, 0x7c, 0x3d, 0x3e, 0x09, 0xc7, 0x08, 0x52, 0x13, + 0x3b, 0x6a, 0x4d, 0x75, 0x54, 0x1f, 0xf6, 0x23, 0x14, 0x9b, 0xd8, 0x7d, 0x99, 0x3f, 0x0c, 0xc8, + 0x69, 0xb5, 0xb6, 0xf6, 0x5d, 0xcf, 0x7a, 0x94, 0xc9, 0x49, 0x60, 0xc2, 0xb7, 0xee, 0x58, 0xd2, + 0x2d, 0x17, 0x20, 0xe3, 0x77, 0x7c, 0x94, 0x06, 0xe6, 0xfa, 0x59, 0x89, 0x64, 0x41, 0xf3, 0xab, + 0x25, 0x92, 0xbf, 0xbc, 0xad, 0x9c, 0x8d, 0x91, 0x3c, 0x6a, 0x69, 0x71, 0xa3, 0x5c, 0x51, 0x36, + 0x57, 0x36, 0x16, 0x97, 0xcb, 0xd9, 0xb8, 0x2f, 0x61, 0x7f, 0x2e, 0x91, 0x7a, 0x20, 0xfb, 0xa0, + 0xfc, 0xcd, 0x18, 0x8c, 0x04, 0x77, 0x60, 0xe8, 0x4d, 0x70, 0x5c, 0x94, 0x4b, 0x6c, 0xec, 0x54, + 0xae, 0x69, 0x16, 0x9d, 0x91, 0x4d, 0x95, 0xad, 0x8e, 0xae, 0x4f, 0x4c, 0x70, 0xac, 0x75, 0xec, + 0xbc, 0xa0, 0x59, 0x64, 0xbe, 0x35, 0x55, 0x07, 0x2d, 0xc1, 0x94, 0x6e, 0x54, 0x6c, 0x47, 0xd5, + 0x6b, 0xaa, 0x55, 0xab, 0x78, 0x85, 0xaa, 0x8a, 0x5a, 0xad, 0x62, 0xdb, 0x36, 0xd8, 0x4a, 0xe8, + 0x72, 0x39, 0xa9, 0x1b, 0xeb, 0x1c, 0xd9, 0x5b, 0x22, 0xe6, 0x38, 0x6a, 0xc8, 0x7f, 0xe3, 0xdd, + 0xfc, 0xf7, 0x2e, 0x48, 0x37, 0x55, 0xb3, 0x82, 0x75, 0xc7, 0xda, 0xa7, 0x79, 0x77, 0x4a, 0x49, + 0x35, 0x55, 0xb3, 0x4c, 0xda, 0x3f, 0x92, 0xed, 0xcf, 0x73, 0x89, 0x54, 0x2a, 0x9b, 0x7e, 0x2e, + 0x91, 0x4a, 0x67, 0x41, 0x7e, 0x2d, 0x0e, 0x19, 0x7f, 0x1e, 0x4e, 0xb6, 0x35, 0x55, 0xba, 0x64, + 0x49, 0x34, 0xa8, 0xdd, 0xdb, 0x33, 0x6b, 0x9f, 0x99, 0x27, 0x6b, 0x59, 0x61, 0x80, 0x65, 0xc7, + 0x0a, 0xa3, 0x24, 0x79, 0x04, 0x71, 0x36, 0xcc, 0xb2, 0x91, 0x94, 0xc2, 0x5b, 0x68, 0x01, 0x06, + 0x5e, 0xb4, 0x29, 0xef, 0x01, 0xca, 0xfb, 0xbe, 0xde, 0xbc, 0x9f, 0x5b, 0xa7, 0xcc, 0xd3, 0xcf, + 0xad, 0x57, 0x56, 0x56, 0x95, 0xe5, 0xb9, 0x25, 0x85, 0x93, 0xa3, 0x13, 0x90, 0x68, 0xa8, 0x2f, + 0xef, 0x07, 0x57, 0x3d, 0x0a, 0xea, 0x77, 0x10, 0x4e, 0x40, 0xe2, 0x1a, 0x56, 0x77, 0x83, 0x6b, + 0x0d, 0x05, 0xdd, 0xc1, 0xc9, 0x30, 0x0b, 0x49, 0x6a, 0x2f, 0x04, 0xc0, 0x2d, 0x96, 0x3d, 0x82, + 0x52, 0x90, 0x98, 0x5f, 0x55, 0xc8, 0x84, 0xc8, 0x42, 0x86, 0x41, 0x2b, 0x6b, 0x8b, 0xe5, 0xf9, + 0x72, 0x36, 0x26, 0x9f, 0x85, 0x01, 0x66, 0x04, 0x32, 0x59, 0x5c, 0x33, 0x64, 0x8f, 0xf0, 0x26, + 0xe7, 0x21, 0x89, 0xa7, 0x9b, 0xcb, 0xc5, 0xb2, 0x92, 0x8d, 0x05, 0x87, 0x3a, 0x91, 0x4d, 0xca, + 0x36, 0x64, 0xfc, 0x89, 0xf8, 0x8f, 0x66, 0x93, 0xfd, 0x15, 0x09, 0x86, 0x7c, 0x89, 0x35, 0xc9, + 0x88, 0xd4, 0x46, 0xc3, 0xb8, 0x56, 0x51, 0x1b, 0x9a, 0x6a, 0x73, 0xd7, 0x00, 0x0a, 0x9a, 0x23, + 0x90, 0x7e, 0x87, 0xee, 0x47, 0x34, 0x45, 0x92, 0xd9, 0x01, 0xf9, 0x53, 0x12, 0x64, 0xc3, 0x99, + 0x6d, 0x48, 0x4c, 0xe9, 0x8d, 0x14, 0x53, 0xfe, 0xa4, 0x04, 0x23, 0xc1, 0x74, 0x36, 0x24, 0xde, + 0x3d, 0x6f, 0xa8, 0x78, 0x7f, 0x14, 0x83, 0xe1, 0x40, 0x12, 0xdb, 0xaf, 0x74, 0x2f, 0xc1, 0x98, + 0x56, 0xc3, 0x4d, 0xd3, 0x70, 0xb0, 0x5e, 0xdd, 0xaf, 0x34, 0xf0, 0x55, 0xdc, 0xc8, 0xc9, 0x34, + 0x68, 0xcc, 0xf6, 0x4e, 0x93, 0x67, 0x16, 0x3d, 0xba, 0x25, 0x42, 0x56, 0x18, 0x5f, 0x2c, 0x95, + 0x97, 0xd7, 0x56, 0x37, 0xca, 0x2b, 0xf3, 0x6f, 0xad, 0x6c, 0xae, 0x5c, 0x5e, 0x59, 0x7d, 0x61, + 0x45, 0xc9, 0x6a, 0x21, 0xb4, 0x3b, 0x38, 0xed, 0xd7, 0x20, 0x1b, 0x16, 0x0a, 0x1d, 0x87, 0x4e, + 0x62, 0x65, 0x8f, 0xa0, 0x71, 0x18, 0x5d, 0x59, 0xad, 0xac, 0x2f, 0x96, 0xca, 0x95, 0xf2, 0xc5, + 0x8b, 0xe5, 0xf9, 0x8d, 0x75, 0x56, 0xf8, 0x70, 0xb1, 0x37, 0x02, 0x13, 0x5c, 0x7e, 0x35, 0x0e, + 0xe3, 0x1d, 0x24, 0x41, 0x73, 0x7c, 0xcb, 0xc2, 0x76, 0x51, 0x8f, 0xf6, 0x23, 0xfd, 0x0c, 0xc9, + 0x19, 0xd6, 0x54, 0xcb, 0xe1, 0x3b, 0x9c, 0x87, 0x80, 0x58, 0x49, 0x77, 0xb4, 0x6d, 0x0d, 0x5b, + 0xbc, 0x4e, 0xc4, 0xf6, 0x31, 0xa3, 0x1e, 0x9c, 0x95, 0x8a, 0x1e, 0x01, 0x64, 0x1a, 0xb6, 0xe6, + 0x68, 0x57, 0x71, 0x45, 0xd3, 0x45, 0x51, 0x89, 0xec, 0x6b, 0x12, 0x4a, 0x56, 0x3c, 0x59, 0xd4, + 0x1d, 0x17, 0x5b, 0xc7, 0x75, 0x35, 0x84, 0x4d, 0x82, 0x79, 0x5c, 0xc9, 0x8a, 0x27, 0x2e, 0xf6, + 0x3d, 0x90, 0xa9, 0x19, 0x2d, 0x92, 0xec, 0x31, 0x3c, 0xb2, 0x76, 0x48, 0xca, 0x10, 0x83, 0xb9, + 0x28, 0x3c, 0x8d, 0xf7, 0xaa, 0x59, 0x19, 0x65, 0x88, 0xc1, 0x18, 0xca, 0x83, 0x30, 0xaa, 0xd6, + 0xeb, 0x16, 0x61, 0x2e, 0x18, 0xb1, 0x8d, 0xc9, 0x88, 0x0b, 0xa6, 0x88, 0xf9, 0xe7, 0x20, 0x25, + 0xec, 0x40, 0x96, 0x6a, 0x62, 0x89, 0x8a, 0xc9, 0x76, 0xdb, 0xb1, 0x53, 0x69, 0x25, 0xa5, 0x8b, + 0x87, 0xf7, 0x40, 0x46, 0xb3, 0x2b, 0x5e, 0x71, 0x3e, 0x36, 0x1d, 0x3b, 0x95, 0x52, 0x86, 0x34, + 0xdb, 0x2d, 0x6c, 0xca, 0x9f, 0x8b, 0xc1, 0x48, 0xf0, 0xe5, 0x02, 0x2a, 0x41, 0xaa, 0x61, 0x54, + 0x55, 0xea, 0x5a, 0xec, 0xcd, 0xd6, 0xa9, 0x88, 0xf7, 0x11, 0x33, 0x4b, 0x1c, 0x5f, 0x71, 0x29, + 0xf3, 0xbf, 0x23, 0x41, 0x4a, 0x80, 0xd1, 0x31, 0x48, 0x98, 0xaa, 0xb3, 0x43, 0xd9, 0x25, 0x8b, + 0xb1, 0xac, 0xa4, 0xd0, 0x36, 0x81, 0xdb, 0xa6, 0xaa, 0x53, 0x17, 0xe0, 0x70, 0xd2, 0x26, 0xe3, + 0xda, 0xc0, 0x6a, 0x8d, 0xee, 0x7a, 0x8c, 0x66, 0x13, 0xeb, 0x8e, 0x2d, 0xc6, 0x95, 0xc3, 0xe7, + 0x39, 0x18, 0x3d, 0x0c, 0x63, 0x8e, 0xa5, 0x6a, 0x8d, 0x00, 0x6e, 0x82, 0xe2, 0x66, 0xc5, 0x03, + 0x17, 0xb9, 0x00, 0x27, 0x04, 0xdf, 0x1a, 0x76, 0xd4, 0xea, 0x0e, 0xae, 0x79, 0x44, 0x03, 0xb4, + 0xba, 0x71, 0x9c, 0x23, 0x94, 0xf8, 0x73, 0x41, 0x2b, 0x7f, 0x53, 0x82, 0x31, 0xb1, 0x4f, 0xab, + 0xb9, 0xc6, 0x5a, 0x06, 0x50, 0x75, 0xdd, 0x70, 0xfc, 0xe6, 0x6a, 0x77, 0xe5, 0x36, 0xba, 0x99, + 0x39, 0x97, 0x48, 0xf1, 0x31, 0xc8, 0x37, 0x01, 0xbc, 0x27, 0x5d, 0xcd, 0x36, 0x05, 0x43, 0xfc, + 0xcd, 0x11, 0x7d, 0xfd, 0xc8, 0x76, 0xf6, 0xc0, 0x40, 0x64, 0x43, 0x87, 0x26, 0x20, 0xb9, 0x85, + 0xeb, 0x9a, 0xce, 0xeb, 0xc1, 0xac, 0x21, 0xea, 0x2f, 0x09, 0xb7, 0xfe, 0x52, 0xfc, 0x90, 0x04, + 0xe3, 0x55, 0xa3, 0x19, 0x96, 0xb7, 0x98, 0x0d, 0x95, 0x17, 0xec, 0x4b, 0xd2, 0xdb, 0x9e, 0xa9, + 0x6b, 0xce, 0x4e, 0x6b, 0x6b, 0xa6, 0x6a, 0x34, 0x67, 0xeb, 0x46, 0x43, 0xd5, 0xeb, 0xde, 0xfb, + 0x53, 0xfa, 0xa3, 0xfa, 0x68, 0x1d, 0xeb, 0x8f, 0xd6, 0x0d, 0xdf, 0xdb, 0xd4, 0x0b, 0xde, 0xcf, + 0xbf, 0x90, 0xa4, 0x5f, 0x88, 0xc5, 0x17, 0xd6, 0x8a, 0x9f, 0x8f, 0xe5, 0x17, 0x58, 0x77, 0x6b, + 0xc2, 0x3c, 0x0a, 0xde, 0x6e, 0xe0, 0x2a, 0x51, 0x19, 0xbe, 0xf3, 0x30, 0x4c, 0xd4, 0x8d, 0xba, + 0x41, 0x39, 0xce, 0x92, 0x5f, 0xfc, 0x8d, 0x6c, 0xda, 0x85, 0xe6, 0x23, 0x5f, 0xdf, 0x16, 0x56, + 0x60, 0x9c, 0x23, 0x57, 0xe8, 0x2b, 0x21, 0xb6, 0xb1, 0x41, 0x3d, 0xcb, 0x6a, 0xb9, 0x5f, 0xfb, + 0x36, 0x5d, 0xd0, 0x95, 0x31, 0x4e, 0x4a, 0x9e, 0xb1, 0xbd, 0x4f, 0x41, 0x81, 0xa3, 0x01, 0x7e, + 0x6c, 0xda, 0x62, 0x2b, 0x82, 0xe3, 0x6f, 0x71, 0x8e, 0xe3, 0x3e, 0x8e, 0xeb, 0x9c, 0xb4, 0x30, + 0x0f, 0xc3, 0x07, 0xe1, 0xf5, 0xaf, 0x39, 0xaf, 0x0c, 0xf6, 0x33, 0x59, 0x80, 0x51, 0xca, 0xa4, + 0xda, 0xb2, 0x1d, 0xa3, 0x49, 0x63, 0x62, 0x6f, 0x36, 0xbf, 0xfd, 0x6d, 0x36, 0x8f, 0x46, 0x08, + 0xd9, 0xbc, 0x4b, 0x55, 0x28, 0x00, 0x7d, 0x0b, 0x56, 0xc3, 0xd5, 0x46, 0x04, 0x87, 0xaf, 0x72, + 0x41, 0x5c, 0xfc, 0xc2, 0x15, 0x98, 0x20, 0xbf, 0x69, 0xc8, 0xf2, 0x4b, 0x12, 0x5d, 0x83, 0xcb, + 0x7d, 0xf3, 0xbd, 0x6c, 0xaa, 0x8e, 0xbb, 0x0c, 0x7c, 0x32, 0xf9, 0x46, 0xb1, 0x8e, 0x1d, 0x07, + 0x5b, 0x76, 0x45, 0x6d, 0x74, 0x12, 0xcf, 0x57, 0xc4, 0xc8, 0x7d, 0xfc, 0xbb, 0xc1, 0x51, 0x5c, + 0x60, 0x94, 0x73, 0x8d, 0x46, 0x61, 0x13, 0x8e, 0x77, 0xf0, 0x8a, 0x3e, 0x78, 0xbe, 0xca, 0x79, + 0x4e, 0xb4, 0x79, 0x06, 0x61, 0xbb, 0x06, 0x02, 0xee, 0x8e, 0x65, 0x1f, 0x3c, 0x3f, 0xc1, 0x79, + 0x22, 0x4e, 0x2b, 0x86, 0x94, 0x70, 0x7c, 0x0e, 0xc6, 0xae, 0x62, 0x6b, 0xcb, 0xb0, 0x79, 0xe1, + 0xa8, 0x0f, 0x76, 0x9f, 0xe4, 0xec, 0x46, 0x39, 0x21, 0xad, 0x24, 0x11, 0x5e, 0x4f, 0x43, 0x6a, + 0x5b, 0xad, 0xe2, 0x3e, 0x58, 0xdc, 0xe0, 0x2c, 0x06, 0x09, 0x3e, 0x21, 0x9d, 0x83, 0x4c, 0xdd, + 0xe0, 0xab, 0x56, 0x34, 0xf9, 0xa7, 0x38, 0xf9, 0x90, 0xa0, 0xe1, 0x2c, 0x4c, 0xc3, 0x6c, 0x35, + 0xc8, 0x92, 0x16, 0xcd, 0xe2, 0xef, 0x08, 0x16, 0x82, 0x86, 0xb3, 0x38, 0x80, 0x59, 0x3f, 0x2d, + 0x58, 0xd8, 0x3e, 0x7b, 0x3e, 0x0b, 0x43, 0x86, 0xde, 0xd8, 0x37, 0xf4, 0x7e, 0x84, 0xf8, 0x0c, + 0xe7, 0x00, 0x9c, 0x84, 0x30, 0xb8, 0x00, 0xe9, 0x7e, 0x07, 0xe2, 0xef, 0x7e, 0x57, 0x4c, 0x0f, + 0x31, 0x02, 0x0b, 0x30, 0x2a, 0x02, 0x94, 0x66, 0xe8, 0x7d, 0xb0, 0xf8, 0x7b, 0x9c, 0xc5, 0x88, + 0x8f, 0x8c, 0xab, 0xe1, 0x60, 0xdb, 0xa9, 0xe3, 0x7e, 0x98, 0x7c, 0x4e, 0xa8, 0xc1, 0x49, 0xb8, + 0x29, 0xb7, 0xb0, 0x5e, 0xdd, 0xe9, 0x8f, 0xc3, 0x2f, 0x09, 0x53, 0x0a, 0x1a, 0xc2, 0x62, 0x1e, + 0x86, 0x9b, 0xaa, 0x65, 0xef, 0xa8, 0x8d, 0xbe, 0x86, 0xe3, 0xef, 0x73, 0x1e, 0x19, 0x97, 0x88, + 0x5b, 0xa4, 0xa5, 0x1f, 0x84, 0xcd, 0xe7, 0x85, 0x45, 0x7c, 0x64, 0x7c, 0xea, 0xd9, 0x0e, 0xad, + 0xb2, 0x1d, 0x84, 0xdb, 0x2f, 0x8b, 0xa9, 0xc7, 0x68, 0x97, 0xfd, 0x1c, 0x2f, 0x40, 0xda, 0xd6, + 0x5e, 0xee, 0x8b, 0xcd, 0x17, 0xc4, 0x48, 0x53, 0x02, 0x42, 0xfc, 0x56, 0x38, 0xd1, 0x71, 0x99, + 0xe8, 0x83, 0xd9, 0x3f, 0xe0, 0xcc, 0x8e, 0x75, 0x58, 0x2a, 0x78, 0x48, 0x38, 0x28, 0xcb, 0x7f, + 0x28, 0x42, 0x02, 0x0e, 0xf1, 0x5a, 0x23, 0xfb, 0x08, 0x5b, 0xdd, 0x3e, 0x98, 0xd5, 0x7e, 0x45, + 0x58, 0x8d, 0xd1, 0x06, 0xac, 0xb6, 0x01, 0xc7, 0x38, 0xc7, 0x83, 0x8d, 0xeb, 0xaf, 0x8a, 0xc0, + 0xca, 0xa8, 0x37, 0x83, 0xa3, 0xfb, 0x76, 0xc8, 0xbb, 0xe6, 0x14, 0x09, 0xab, 0x5d, 0x69, 0xaa, + 0x66, 0x1f, 0x9c, 0x7f, 0x8d, 0x73, 0x16, 0x11, 0xdf, 0xcd, 0x78, 0xed, 0x65, 0xd5, 0x24, 0xcc, + 0xdf, 0x02, 0x39, 0xc1, 0xbc, 0xa5, 0x5b, 0xb8, 0x6a, 0xd4, 0x75, 0xed, 0x65, 0x5c, 0xeb, 0x83, + 0xf5, 0xaf, 0x87, 0x86, 0x6a, 0xd3, 0x47, 0x4e, 0x38, 0x2f, 0x42, 0xd6, 0xcd, 0x55, 0x2a, 0x5a, + 0xd3, 0x34, 0x2c, 0x27, 0x82, 0xe3, 0x17, 0xc5, 0x48, 0xb9, 0x74, 0x8b, 0x94, 0xac, 0x50, 0x86, + 0x11, 0xda, 0xec, 0xd7, 0x25, 0xbf, 0xc4, 0x19, 0x0d, 0x7b, 0x54, 0x3c, 0x70, 0x54, 0x8d, 0xa6, + 0xa9, 0x5a, 0xfd, 0xc4, 0xbf, 0x7f, 0x24, 0x02, 0x07, 0x27, 0xe1, 0x81, 0xc3, 0xd9, 0x37, 0x31, + 0x59, 0xed, 0xfb, 0xe0, 0xf0, 0x65, 0x11, 0x38, 0x04, 0x0d, 0x67, 0x21, 0x12, 0x86, 0x3e, 0x58, + 0xfc, 0x63, 0xc1, 0x42, 0xd0, 0x10, 0x16, 0xcf, 0x7b, 0x0b, 0xad, 0x85, 0xeb, 0x9a, 0xed, 0x58, + 0x2c, 0x4d, 0xee, 0xcd, 0xea, 0x9f, 0x7c, 0x37, 0x98, 0x84, 0x29, 0x3e, 0x52, 0x12, 0x89, 0x78, + 0xd9, 0x95, 0xee, 0xa2, 0xa2, 0x05, 0xfb, 0x0d, 0x11, 0x89, 0x7c, 0x64, 0x44, 0x36, 0x5f, 0x86, + 0x48, 0xcc, 0x5e, 0x25, 0x7b, 0x87, 0x3e, 0xd8, 0xfd, 0xd3, 0x90, 0x70, 0xeb, 0x82, 0x96, 0xf0, + 0xf4, 0xe5, 0x3f, 0x2d, 0x7d, 0x17, 0xef, 0xf7, 0xe5, 0x9d, 0xff, 0x2c, 0x94, 0xff, 0x6c, 0x32, + 0x4a, 0x16, 0x43, 0x46, 0x43, 0xf9, 0x14, 0x8a, 0x3a, 0x3f, 0x94, 0xfb, 0xa9, 0xef, 0x73, 0x7d, + 0x83, 0xe9, 0x54, 0x61, 0x89, 0x38, 0x79, 0x30, 0xe9, 0x89, 0x66, 0xf6, 0xde, 0xef, 0xbb, 0x7e, + 0x1e, 0xc8, 0x79, 0x0a, 0x17, 0x61, 0x38, 0x90, 0xf0, 0x44, 0xb3, 0x7a, 0x1f, 0x67, 0x95, 0xf1, + 0xe7, 0x3b, 0x85, 0xb3, 0x90, 0x20, 0xc9, 0x4b, 0x34, 0xf9, 0x5f, 0xe7, 0xe4, 0x14, 0xbd, 0xf0, + 0x66, 0x48, 0x89, 0xa4, 0x25, 0x9a, 0xf4, 0xfd, 0x9c, 0xd4, 0x25, 0x21, 0xe4, 0x22, 0x61, 0x89, + 0x26, 0xff, 0x1b, 0x82, 0x5c, 0x90, 0x10, 0xf2, 0xfe, 0x4d, 0xf8, 0x95, 0x9f, 0x4e, 0xf0, 0x45, + 0x47, 0xd8, 0xee, 0x02, 0x0c, 0xf2, 0x4c, 0x25, 0x9a, 0xfa, 0x83, 0xbc, 0x73, 0x41, 0x51, 0x78, + 0x0a, 0x92, 0x7d, 0x1a, 0xfc, 0x67, 0x38, 0x29, 0xc3, 0x2f, 0xcc, 0xc3, 0x90, 0x2f, 0x3b, 0x89, + 0x26, 0xff, 0x5b, 0x9c, 0xdc, 0x4f, 0x45, 0x44, 0xe7, 0xd9, 0x49, 0x34, 0x83, 0x0f, 0x09, 0xd1, + 0x39, 0x05, 0x31, 0x9b, 0x48, 0x4c, 0xa2, 0xa9, 0x3f, 0x2c, 0xac, 0x2e, 0x48, 0x0a, 0xcf, 0x42, + 0xda, 0x5d, 0x6c, 0xa2, 0xe9, 0x3f, 0xc2, 0xe9, 0x3d, 0x1a, 0x62, 0x01, 0xdf, 0x62, 0x17, 0xcd, + 0xe2, 0x67, 0x85, 0x05, 0x7c, 0x54, 0x64, 0x1a, 0x85, 0x13, 0x98, 0x68, 0x4e, 0x1f, 0x15, 0xd3, + 0x28, 0x94, 0xbf, 0x90, 0xd1, 0xa4, 0x31, 0x3f, 0x9a, 0xc5, 0xcf, 0x89, 0xd1, 0xa4, 0xf8, 0x44, + 0x8c, 0x70, 0x46, 0x10, 0xcd, 0xe3, 0x6f, 0x0b, 0x31, 0x42, 0x09, 0x41, 0x61, 0x0d, 0x50, 0x7b, + 0x36, 0x10, 0xcd, 0xef, 0x63, 0x9c, 0xdf, 0x58, 0x5b, 0x32, 0x50, 0x78, 0x01, 0x8e, 0x75, 0xce, + 0x04, 0xa2, 0xb9, 0x7e, 0xfc, 0xfb, 0xa1, 0xbd, 0x9b, 0x3f, 0x11, 0x28, 0x6c, 0x78, 0x4b, 0x8a, + 0x3f, 0x0b, 0x88, 0x66, 0xfb, 0xea, 0xf7, 0x83, 0x81, 0xdb, 0x9f, 0x04, 0x14, 0xe6, 0x00, 0xbc, + 0x05, 0x38, 0x9a, 0xd7, 0x27, 0x39, 0x2f, 0x1f, 0x11, 0x99, 0x1a, 0x7c, 0xfd, 0x8d, 0xa6, 0xbf, + 0x21, 0xa6, 0x06, 0xa7, 0x20, 0x53, 0x43, 0x2c, 0xbd, 0xd1, 0xd4, 0x9f, 0x12, 0x53, 0x43, 0x90, + 0x10, 0xcf, 0xf6, 0xad, 0x6e, 0xd1, 0x1c, 0x3e, 0x23, 0x3c, 0xdb, 0x47, 0x55, 0x58, 0x81, 0xb1, + 0xb6, 0x05, 0x31, 0x9a, 0xd5, 0x2f, 0x70, 0x56, 0xd9, 0xf0, 0x7a, 0xe8, 0x5f, 0xbc, 0xf8, 0x62, + 0x18, 0xcd, 0xed, 0xb3, 0xa1, 0xc5, 0x8b, 0xaf, 0x85, 0x85, 0x0b, 0x90, 0xd2, 0x5b, 0x8d, 0x06, + 0x99, 0x3c, 0xa8, 0xf7, 0x99, 0xbf, 0xdc, 0x7f, 0xfd, 0x01, 0xb7, 0x8e, 0x20, 0x28, 0x9c, 0x85, + 0x24, 0x6e, 0x6e, 0xe1, 0x5a, 0x14, 0xe5, 0x77, 0x7e, 0x20, 0x02, 0x26, 0xc1, 0x2e, 0x3c, 0x0b, + 0xc0, 0x4a, 0x23, 0xf4, 0xf5, 0x60, 0x04, 0xed, 0x7f, 0xfb, 0x01, 0x3f, 0x8d, 0xe3, 0x91, 0x78, + 0x0c, 0xd8, 0xd9, 0x9e, 0xde, 0x0c, 0xbe, 0x1b, 0x64, 0x40, 0x47, 0xe4, 0x69, 0x18, 0x7c, 0xd1, + 0x36, 0x74, 0x47, 0xad, 0x47, 0x51, 0xff, 0x77, 0x4e, 0x2d, 0xf0, 0x89, 0xc1, 0x9a, 0x86, 0x85, + 0x1d, 0xb5, 0x6e, 0x47, 0xd1, 0xfe, 0x0f, 0x4e, 0xeb, 0x12, 0x10, 0xe2, 0xaa, 0x6a, 0x3b, 0xfd, + 0xe8, 0xfd, 0x27, 0x82, 0x58, 0x10, 0x10, 0xa1, 0xc9, 0xef, 0x5d, 0xbc, 0x1f, 0x45, 0xfb, 0x3d, + 0x21, 0x34, 0xc7, 0x2f, 0xbc, 0x19, 0xd2, 0xe4, 0x27, 0x3b, 0x62, 0x17, 0x41, 0xfc, 0xa7, 0x9c, + 0xd8, 0xa3, 0x20, 0x3d, 0xdb, 0x4e, 0xcd, 0xd1, 0xa2, 0x8d, 0x7d, 0x8b, 0x8f, 0xb4, 0xc0, 0x2f, + 0xcc, 0xc1, 0x90, 0xed, 0xd4, 0x6a, 0x2d, 0x9e, 0x9f, 0x46, 0x90, 0xff, 0xd9, 0x0f, 0xdc, 0x92, + 0x85, 0x4b, 0x43, 0x46, 0xfb, 0xda, 0xae, 0x63, 0x1a, 0xf4, 0x15, 0x48, 0x14, 0x87, 0xef, 0x73, + 0x0e, 0x3e, 0x92, 0xc2, 0x3c, 0x64, 0x88, 0x2e, 0x16, 0x36, 0x31, 0x7d, 0x5f, 0x15, 0xc1, 0xe2, + 0xcf, 0xb9, 0x01, 0x02, 0x44, 0xc5, 0x9f, 0xfc, 0xea, 0x6b, 0x93, 0xd2, 0x37, 0x5e, 0x9b, 0x94, + 0xfe, 0xe8, 0xb5, 0x49, 0xe9, 0xc3, 0xdf, 0x9a, 0x3c, 0xf2, 0x8d, 0x6f, 0x4d, 0x1e, 0xf9, 0xbd, + 0x6f, 0x4d, 0x1e, 0xe9, 0x5c, 0x36, 0x86, 0x05, 0x63, 0xc1, 0x60, 0x05, 0xe3, 0xb7, 0xc9, 0x81, + 0x72, 0x71, 0xdd, 0xf0, 0xaa, 0xb5, 0xee, 0x26, 0x07, 0xfe, 0x5c, 0x22, 0x1b, 0xe6, 0x60, 0x2d, + 0x57, 0xd5, 0xf7, 0xbb, 0xdc, 0xc1, 0xc9, 0x77, 0x2c, 0x0c, 0xcb, 0x6f, 0x82, 0xf8, 0x9c, 0xbe, + 0x8f, 0x4e, 0xb0, 0x98, 0x57, 0x69, 0x59, 0x0d, 0x7e, 0xf4, 0x6b, 0x90, 0xb4, 0x37, 0xad, 0x06, + 0x9a, 0xf0, 0xce, 0x67, 0x4a, 0xa7, 0x32, 0xfc, 0xd0, 0x65, 0x21, 0xf1, 0xbd, 0xcf, 0x4c, 0x1d, + 0x29, 0xee, 0x86, 0x35, 0xfc, 0x4a, 0xa4, 0x96, 0xa9, 0x39, 0x7d, 0x9f, 0x2a, 0xb9, 0x26, 0xbd, + 0x2d, 0x49, 0xfa, 0xb0, 0x45, 0x61, 0x7b, 0x32, 0x5c, 0xd8, 0x7e, 0x01, 0x37, 0x1a, 0x97, 0x75, + 0xe3, 0x9a, 0xbe, 0x41, 0xd0, 0xb6, 0x06, 0x28, 0x8f, 0x27, 0xe0, 0xc3, 0x31, 0x98, 0x0a, 0xeb, + 0x4d, 0x1c, 0xc7, 0x76, 0xd4, 0xa6, 0xd9, 0xed, 0x06, 0xd2, 0x05, 0x48, 0x6f, 0x08, 0x1c, 0x94, + 0x83, 0x41, 0x1b, 0x57, 0x0d, 0xbd, 0x66, 0x53, 0x65, 0xe3, 0x8a, 0x68, 0x12, 0x65, 0x75, 0x55, + 0x37, 0x6c, 0x7e, 0x40, 0x92, 0x35, 0x8a, 0x3f, 0x2f, 0x1d, 0x6c, 0x24, 0x47, 0xdc, 0xae, 0x84, + 0xa6, 0x0f, 0xf7, 0x2a, 0xff, 0x53, 0x2b, 0x78, 0x2a, 0xf8, 0x6a, 0xfd, 0xfd, 0x9a, 0xe4, 0x3d, + 0x71, 0x38, 0x51, 0x35, 0xec, 0xa6, 0x61, 0x57, 0xd8, 0x08, 0xb3, 0x06, 0x37, 0x46, 0xc6, 0xff, + 0xa8, 0x8f, 0xfa, 0xff, 0x25, 0x18, 0xa1, 0xb3, 0x80, 0x56, 0x3e, 0x69, 0xe0, 0x89, 0x5c, 0x2b, + 0xbe, 0xf6, 0xef, 0x93, 0xd4, 0x6b, 0x86, 0x5d, 0x42, 0x7a, 0xb4, 0x63, 0x03, 0x26, 0xb4, 0xa6, + 0xd9, 0xc0, 0xf4, 0x1d, 0x50, 0xc5, 0x7d, 0x16, 0xcd, 0xef, 0xeb, 0x9c, 0xdf, 0xb8, 0x47, 0xbe, + 0x28, 0xa8, 0x0b, 0x4b, 0x30, 0xa6, 0x56, 0xab, 0xd8, 0x0c, 0xb0, 0x8c, 0x98, 0xa1, 0x42, 0xc0, + 0x2c, 0xa7, 0x74, 0xb9, 0x15, 0x9f, 0xed, 0x36, 0xb6, 0x6f, 0xbb, 0xdf, 0x37, 0x68, 0x16, 0xae, + 0x63, 0xfd, 0x51, 0x1d, 0x3b, 0xd7, 0x0c, 0x6b, 0x97, 0x9b, 0xf7, 0x51, 0xd6, 0x95, 0x18, 0x84, + 0xf7, 0xc5, 0x61, 0x92, 0x3d, 0x98, 0xdd, 0x52, 0x6d, 0x3c, 0x7b, 0xf5, 0xf1, 0x2d, 0xec, 0xa8, + 0x8f, 0xcf, 0x56, 0x0d, 0x4d, 0xe7, 0x23, 0x31, 0xce, 0xc7, 0x85, 0x3c, 0x9f, 0xe1, 0xcf, 0xbb, + 0x4c, 0xcc, 0x05, 0x48, 0xcc, 0x1b, 0x9a, 0x4e, 0x3c, 0xb2, 0x86, 0x75, 0xa3, 0xc9, 0xa7, 0x25, + 0x6b, 0xa0, 0x7b, 0x61, 0x40, 0x6d, 0x1a, 0x2d, 0xdd, 0x61, 0xaf, 0xaf, 0x8a, 0x43, 0x5f, 0xbd, + 0x39, 0x75, 0xe4, 0xf7, 0x6f, 0x4e, 0xc5, 0x17, 0x75, 0x47, 0xe1, 0x8f, 0x0a, 0x89, 0xd7, 0x3f, + 0x3d, 0x25, 0xc9, 0xcf, 0xc1, 0x60, 0x09, 0x57, 0x0f, 0xc3, 0xab, 0x84, 0xab, 0x21, 0x5e, 0x0f, + 0x41, 0x6a, 0x51, 0x77, 0xd8, 0x99, 0xd9, 0xbb, 0x21, 0xae, 0xe9, 0xec, 0x14, 0x56, 0xa8, 0x7f, + 0x02, 0x27, 0xa8, 0x25, 0x5c, 0x75, 0x51, 0x6b, 0xb8, 0x1a, 0x46, 0x25, 0xec, 0x09, 0xbc, 0x58, + 0xfa, 0xbd, 0xff, 0x3c, 0x79, 0xe4, 0x95, 0xd7, 0x26, 0x8f, 0x74, 0x1d, 0x09, 0x7f, 0x38, 0xe4, + 0x26, 0xe6, 0x43, 0x60, 0xd7, 0x76, 0x67, 0x9d, 0xc0, 0x5c, 0xf8, 0x9b, 0x31, 0x98, 0x6c, 0x73, + 0x71, 0xbe, 0x30, 0x74, 0x8b, 0x0e, 0x05, 0x48, 0x95, 0xc4, 0x7a, 0x73, 0xd0, 0xe0, 0xf0, 0x73, + 0x07, 0x0c, 0x0e, 0xc3, 0xa2, 0x27, 0x11, 0x1b, 0x4e, 0x47, 0xc7, 0x06, 0x21, 0xff, 0x21, 0x42, + 0xc3, 0xe7, 0x13, 0x70, 0x37, 0xbd, 0x14, 0x62, 0x35, 0x35, 0xdd, 0x99, 0xad, 0x5a, 0xfb, 0xa6, + 0x43, 0x97, 0x13, 0x63, 0x9b, 0x5b, 0x63, 0xcc, 0x7b, 0x3c, 0xc3, 0x1e, 0x77, 0x71, 0xc9, 0x6d, + 0x48, 0xae, 0x11, 0x3a, 0x62, 0x08, 0xc7, 0x70, 0xd4, 0x06, 0x37, 0x10, 0x6b, 0x10, 0x28, 0xbb, + 0x48, 0x12, 0x63, 0x50, 0x4d, 0xdc, 0x21, 0x69, 0x60, 0x75, 0x9b, 0x1d, 0xdc, 0x8d, 0xd3, 0x25, + 0x24, 0x45, 0x00, 0xf4, 0x8c, 0xee, 0x04, 0x24, 0xd5, 0x16, 0x7b, 0xe5, 0x1c, 0x27, 0x6b, 0x0b, + 0x6d, 0xc8, 0x97, 0x61, 0x90, 0xbf, 0xe6, 0x42, 0x59, 0x88, 0xef, 0xe2, 0x7d, 0xda, 0x4f, 0x46, + 0x21, 0x3f, 0xd1, 0x0c, 0x24, 0xa9, 0xf0, 0xfc, 0x46, 0x42, 0x6e, 0xa6, 0x4d, 0xfa, 0x19, 0x2a, + 0xa4, 0xc2, 0xd0, 0xe4, 0xe7, 0x20, 0x55, 0x32, 0x9a, 0x9a, 0x6e, 0x04, 0xb9, 0xa5, 0x19, 0x37, + 0x2a, 0xb3, 0xd9, 0xe2, 0xae, 0xaf, 0xb0, 0x06, 0x3a, 0x06, 0x03, 0xec, 0x20, 0x37, 0x7f, 0x6d, + 0xce, 0x5b, 0xf2, 0x3c, 0x0c, 0x52, 0xde, 0xab, 0x26, 0x42, 0xfc, 0x66, 0x0f, 0x3f, 0x31, 0x4e, + 0xa3, 0x24, 0x67, 0x1f, 0xf3, 0x84, 0x45, 0x90, 0xa8, 0xa9, 0x8e, 0xca, 0xf5, 0xa6, 0xbf, 0xe5, + 0x67, 0x20, 0xc5, 0x99, 0xd8, 0xe8, 0x0c, 0xc4, 0x0d, 0xd3, 0xe6, 0x2f, 0xbe, 0xf3, 0xdd, 0x54, + 0x59, 0x35, 0x8b, 0x09, 0x32, 0x69, 0x14, 0x82, 0x5c, 0x54, 0xba, 0xce, 0x92, 0xf3, 0x3e, 0x47, + 0xf2, 0x0d, 0xb9, 0xef, 0x27, 0x1b, 0xd2, 0x36, 0x77, 0x70, 0x9d, 0xe5, 0x33, 0x31, 0x98, 0xf4, + 0x3d, 0xbd, 0x8a, 0x2d, 0xb2, 0xd7, 0x63, 0x13, 0x8c, 0x7b, 0x0b, 0xf2, 0x09, 0xc9, 0x9f, 0x77, + 0x71, 0x97, 0x37, 0x43, 0x7c, 0xce, 0x34, 0x51, 0x1e, 0x52, 0xec, 0x05, 0xb7, 0xc1, 0xfc, 0x25, + 0xa1, 0xb8, 0x6d, 0xf2, 0xcc, 0x36, 0xb6, 0x9d, 0x6b, 0xaa, 0xe5, 0x5e, 0x61, 0x12, 0x6d, 0xf9, + 0x69, 0x48, 0xcf, 0x1b, 0xba, 0x8d, 0x75, 0xbb, 0x45, 0xa7, 0xde, 0x56, 0xc3, 0xa8, 0xee, 0x72, + 0x0e, 0xac, 0x41, 0x0c, 0xae, 0x9a, 0x26, 0xa5, 0x4c, 0x28, 0xe4, 0x27, 0x0b, 0x53, 0xc5, 0xf5, + 0xae, 0x26, 0x7a, 0xfa, 0xe0, 0x26, 0xe2, 0x4a, 0xba, 0x36, 0xfa, 0x03, 0x09, 0x4e, 0xb6, 0x4f, + 0xa8, 0x5d, 0xbc, 0x6f, 0x1f, 0x74, 0x3e, 0x9d, 0x87, 0xf4, 0x1a, 0xbd, 0x47, 0x7c, 0x19, 0xef, + 0xa3, 0x3c, 0x0c, 0xe2, 0xda, 0x99, 0xb3, 0x67, 0x1f, 0x7f, 0x9a, 0x79, 0xfb, 0xa5, 0x23, 0x8a, + 0x00, 0x14, 0x52, 0x44, 0xab, 0xd7, 0x3f, 0x33, 0x25, 0x15, 0x93, 0x10, 0xb7, 0x5b, 0xcd, 0x3b, + 0xea, 0x03, 0xaf, 0x26, 0x61, 0xda, 0x4f, 0x49, 0x03, 0xd0, 0x55, 0xb5, 0xa1, 0xd5, 0x54, 0xef, + 0x86, 0x77, 0xd6, 0xa7, 0x23, 0xc5, 0xe8, 0xac, 0x62, 0xbe, 0xa7, 0xa5, 0xe4, 0x5f, 0x97, 0x20, + 0x73, 0x45, 0x70, 0x5e, 0xc7, 0x0e, 0xba, 0x00, 0xe0, 0xf6, 0x24, 0xa6, 0xc5, 0x5d, 0x33, 0xe1, + 0xbe, 0x66, 0x5c, 0x1a, 0xc5, 0x87, 0x8e, 0x9e, 0xa2, 0x8e, 0x66, 0x1a, 0x36, 0xbf, 0xdf, 0x12, + 0x41, 0xea, 0x22, 0xa3, 0x47, 0x00, 0xd1, 0x08, 0x56, 0xb9, 0x6a, 0x38, 0x9a, 0x5e, 0xaf, 0x98, + 0xc6, 0x35, 0x7e, 0x19, 0x30, 0xae, 0x64, 0xe9, 0x93, 0x2b, 0xf4, 0xc1, 0x1a, 0x81, 0x13, 0xa1, + 0xd3, 0x2e, 0x17, 0xb2, 0x5a, 0xa8, 0xb5, 0x9a, 0x85, 0x6d, 0x9b, 0x07, 0x29, 0xd1, 0x44, 0x17, + 0x60, 0xd0, 0x6c, 0x6d, 0x55, 0x44, 0x44, 0x18, 0x3a, 0x73, 0xb2, 0xd3, 0xfc, 0x16, 0xe3, 0xcf, + 0x67, 0xf8, 0x80, 0xd9, 0xda, 0x22, 0xde, 0x70, 0x0f, 0x64, 0x3a, 0x08, 0x33, 0x74, 0xd5, 0x93, + 0x83, 0x5e, 0x4f, 0xe7, 0x1a, 0x54, 0x4c, 0x4b, 0x33, 0x2c, 0xcd, 0xd9, 0xa7, 0xa7, 0x53, 0xe2, + 0x4a, 0x56, 0x3c, 0x58, 0xe3, 0x70, 0x79, 0x17, 0x46, 0xd7, 0x69, 0x2a, 0xe5, 0x49, 0x7e, 0xd6, + 0x93, 0x4f, 0x8a, 0x96, 0xaf, 0xab, 0x64, 0xb1, 0x36, 0xc9, 0x8a, 0xcf, 0x77, 0xf5, 0xce, 0xa7, + 0x0e, 0xee, 0x9d, 0xc1, 0xc5, 0xfd, 0x4f, 0x4e, 0x04, 0x26, 0x1f, 0xcf, 0x9c, 0x7d, 0xe1, 0xa9, + 0x5f, 0xc7, 0x8c, 0xda, 0x41, 0xe4, 0x7b, 0x2f, 0x9a, 0xf9, 0x88, 0x30, 0x99, 0x8f, 0x9c, 0x42, + 0xf2, 0xd3, 0x30, 0xbc, 0xa6, 0x5a, 0xce, 0x3a, 0x76, 0x2e, 0x61, 0xb5, 0x86, 0xad, 0xe0, 0xaa, + 0x3a, 0x2c, 0x56, 0x55, 0x04, 0x09, 0xba, 0x74, 0xb2, 0x55, 0x85, 0xfe, 0x96, 0x77, 0x20, 0x41, + 0x4f, 0xa8, 0xb9, 0x2b, 0x2e, 0xa7, 0x60, 0x2b, 0x2e, 0x89, 0x95, 0xfb, 0x0e, 0xb6, 0xc5, 0x86, + 0x8d, 0x36, 0xd0, 0x93, 0x62, 0xdd, 0x8c, 0xf7, 0x5e, 0x37, 0xb9, 0x23, 0xf2, 0xd5, 0xb3, 0x01, + 0x83, 0x45, 0x12, 0x6a, 0x17, 0x4b, 0xae, 0x20, 0x92, 0x27, 0x08, 0x5a, 0x86, 0x51, 0x53, 0xb5, + 0x1c, 0x7a, 0x34, 0x7f, 0x87, 0x6a, 0xc1, 0x7d, 0x7d, 0xaa, 0x7d, 0xe6, 0x05, 0x94, 0xe5, 0xbd, + 0x0c, 0x9b, 0x7e, 0xa0, 0xfc, 0xc7, 0x09, 0x18, 0xe0, 0xc6, 0x78, 0x33, 0x0c, 0x72, 0xb3, 0x72, + 0xef, 0xbc, 0x7b, 0xa6, 0x7d, 0xe1, 0x99, 0x71, 0x17, 0x08, 0xce, 0x4f, 0xd0, 0xa0, 0x07, 0x20, + 0x55, 0xdd, 0x51, 0x35, 0xbd, 0xa2, 0xd5, 0x44, 0x56, 0xfb, 0xda, 0xcd, 0xa9, 0xc1, 0x79, 0x02, + 0x5b, 0x2c, 0x29, 0x83, 0xf4, 0xe1, 0x62, 0x8d, 0xac, 0xf4, 0x3b, 0x58, 0xab, 0xef, 0x38, 0x7c, + 0x86, 0xf1, 0x16, 0x3a, 0x0f, 0x09, 0xe2, 0x10, 0xfc, 0xe6, 0x56, 0xbe, 0x6d, 0x6f, 0xe1, 0x6e, + 0xf0, 0x8a, 0x29, 0xd2, 0xf1, 0x87, 0xff, 0x70, 0x4a, 0x52, 0x28, 0x05, 0x9a, 0x87, 0xe1, 0x86, + 0x6a, 0x3b, 0x15, 0xba, 0x42, 0x91, 0xee, 0x93, 0x94, 0xc5, 0x89, 0x76, 0x83, 0x70, 0xc3, 0x72, + 0xd1, 0x87, 0x08, 0x15, 0x03, 0xd5, 0xd0, 0x29, 0xc8, 0x52, 0x26, 0x55, 0xa3, 0xd9, 0xd4, 0x1c, + 0x96, 0x3b, 0x0d, 0x50, 0xbb, 0x8f, 0x10, 0xf8, 0x3c, 0x05, 0xd3, 0x0c, 0xea, 0x2e, 0x48, 0xd3, + 0xab, 0x22, 0x14, 0x85, 0x1d, 0x8b, 0x4c, 0x11, 0x00, 0x7d, 0xf8, 0x20, 0x8c, 0x7a, 0xf1, 0x91, + 0xa1, 0xa4, 0x18, 0x17, 0x0f, 0x4c, 0x11, 0x1f, 0x83, 0x09, 0x1d, 0xef, 0xd1, 0x83, 0x9a, 0x01, + 0xec, 0x34, 0xc5, 0x46, 0xe4, 0xd9, 0x95, 0x20, 0xc5, 0xfd, 0x30, 0x52, 0x15, 0xc6, 0x67, 0xb8, + 0x40, 0x71, 0x87, 0x5d, 0x28, 0x45, 0x3b, 0x01, 0x29, 0xd5, 0x34, 0x19, 0xc2, 0x10, 0x8f, 0x8f, + 0xa6, 0x49, 0x1f, 0x9d, 0x86, 0x31, 0xaa, 0xa3, 0x85, 0xed, 0x56, 0xc3, 0xe1, 0x4c, 0x32, 0x14, + 0x67, 0x94, 0x3c, 0x50, 0x18, 0x9c, 0xe2, 0xde, 0x0b, 0xc3, 0xf8, 0xaa, 0x56, 0xc3, 0x7a, 0x15, + 0x33, 0xbc, 0x61, 0x8a, 0x97, 0x11, 0x40, 0x8a, 0xf4, 0x10, 0xb8, 0x71, 0xaf, 0x22, 0x62, 0xf2, + 0x08, 0xe3, 0x27, 0xe0, 0x73, 0x0c, 0x2c, 0xe7, 0x20, 0x51, 0x52, 0x1d, 0x95, 0x24, 0x10, 0xce, + 0x1e, 0x5b, 0x68, 0x32, 0x0a, 0xf9, 0x29, 0xbf, 0x1e, 0x83, 0xc4, 0x15, 0xc3, 0xc1, 0xe8, 0x09, + 0x5f, 0x82, 0x37, 0xd2, 0xc9, 0x9f, 0xd7, 0xb5, 0xba, 0x8e, 0x6b, 0xcb, 0x76, 0xdd, 0x77, 0x5f, + 0xdb, 0x73, 0xa7, 0x58, 0xc0, 0x9d, 0x26, 0x20, 0x69, 0x19, 0x2d, 0xbd, 0x26, 0x4e, 0x14, 0xd2, + 0x06, 0x2a, 0x43, 0xca, 0xf5, 0x92, 0x44, 0x94, 0x97, 0x8c, 0x12, 0x2f, 0x21, 0x3e, 0xcc, 0x01, + 0xca, 0xe0, 0x16, 0x77, 0x96, 0x22, 0xa4, 0xdd, 0xe0, 0xc5, 0xbd, 0xad, 0x3f, 0x87, 0xf5, 0xc8, + 0xc8, 0x62, 0xe2, 0x8e, 0xbd, 0x6b, 0x3c, 0xe6, 0x71, 0x59, 0xf7, 0x01, 0xb7, 0x5e, 0xc0, 0xad, + 0xf8, 0xdd, 0xf1, 0x41, 0xaa, 0x97, 0xe7, 0x56, 0xec, 0xfe, 0xf8, 0x49, 0x48, 0xdb, 0x5a, 0x5d, + 0x57, 0x9d, 0x96, 0x85, 0xb9, 0xe7, 0x79, 0x00, 0xf9, 0x2b, 0x12, 0x0c, 0x30, 0x4f, 0xf6, 0xd9, + 0x4d, 0xea, 0x6c, 0xb7, 0x58, 0x37, 0xbb, 0xc5, 0x0f, 0x6f, 0xb7, 0x39, 0x00, 0x57, 0x18, 0x9b, + 0xdf, 0xfd, 0xed, 0x90, 0x31, 0x30, 0x11, 0xd7, 0xb5, 0x3a, 0x9f, 0xa8, 0x3e, 0x22, 0xf9, 0x0f, + 0x24, 0x92, 0xa4, 0xf2, 0xe7, 0x68, 0x0e, 0x86, 0x85, 0x5c, 0x95, 0xed, 0x86, 0x5a, 0xe7, 0xbe, + 0x73, 0x77, 0x57, 0xe1, 0x2e, 0x36, 0xd4, 0xba, 0x32, 0xc4, 0xe5, 0x21, 0x8d, 0xce, 0xe3, 0x10, + 0xeb, 0x32, 0x0e, 0x81, 0x81, 0x8f, 0x1f, 0x6e, 0xe0, 0x03, 0x43, 0x94, 0x08, 0x0f, 0xd1, 0x17, + 0x63, 0x74, 0xb3, 0x62, 0x1a, 0xb6, 0xda, 0xf8, 0x51, 0xcc, 0x88, 0xbb, 0x20, 0x6d, 0x1a, 0x8d, + 0x0a, 0x7b, 0xc2, 0x4e, 0xda, 0xa6, 0x4c, 0xa3, 0xa1, 0xb4, 0x0d, 0x7b, 0xf2, 0x36, 0x4d, 0x97, + 0x81, 0xdb, 0x60, 0xb5, 0xc1, 0xb0, 0xd5, 0x2c, 0xc8, 0x30, 0x53, 0xf0, 0xb5, 0xec, 0x31, 0x62, + 0x03, 0xba, 0x38, 0x4a, 0xed, 0x6b, 0x2f, 0x13, 0x9b, 0x61, 0x2a, 0x1c, 0x8f, 0x50, 0xb0, 0xd0, + 0xdf, 0x69, 0x97, 0xeb, 0x77, 0x4b, 0x85, 0xe3, 0xc9, 0x3f, 0x2f, 0x01, 0x2c, 0x11, 0xcb, 0x52, + 0x7d, 0xc9, 0x2a, 0x64, 0x53, 0x11, 0x2a, 0x81, 0x9e, 0x27, 0xbb, 0x0d, 0x1a, 0xef, 0x3f, 0x63, + 0xfb, 0xe5, 0x9e, 0x87, 0x61, 0xcf, 0x19, 0x6d, 0x2c, 0x84, 0x99, 0xec, 0x91, 0x55, 0xaf, 0x63, + 0x47, 0xc9, 0x5c, 0xf5, 0xb5, 0xe4, 0x7f, 0x29, 0x41, 0x9a, 0xca, 0xb4, 0x8c, 0x1d, 0x35, 0x30, + 0x86, 0xd2, 0xe1, 0xc7, 0xf0, 0x6e, 0x00, 0xc6, 0xc6, 0xd6, 0x5e, 0xc6, 0xdc, 0xb3, 0xd2, 0x14, + 0xb2, 0xae, 0xbd, 0x8c, 0xd1, 0x39, 0xd7, 0xe0, 0xf1, 0xde, 0x06, 0x17, 0x59, 0x37, 0x37, 0xfb, + 0x71, 0x18, 0xa4, 0x9f, 0xc0, 0xd9, 0xb3, 0x79, 0x22, 0x3d, 0xa0, 0xb7, 0x9a, 0x1b, 0x7b, 0xb6, + 0xfc, 0x22, 0x0c, 0x6e, 0xec, 0xb1, 0xda, 0xc7, 0x5d, 0x90, 0xb6, 0x0c, 0x83, 0xaf, 0xc9, 0x2c, + 0x17, 0x4a, 0x11, 0x00, 0x5d, 0x82, 0xc4, 0x7e, 0x3f, 0xe6, 0xed, 0xf7, 0xbd, 0x82, 0x45, 0xbc, + 0xaf, 0x82, 0xc5, 0xe9, 0xff, 0x20, 0xc1, 0x90, 0x2f, 0x3e, 0xa0, 0xc7, 0xe1, 0x68, 0x71, 0x69, + 0x75, 0xfe, 0x72, 0x65, 0xb1, 0x54, 0xb9, 0xb8, 0x34, 0xb7, 0xe0, 0xdd, 0x25, 0xc9, 0x1f, 0xbb, + 0x7e, 0x63, 0x1a, 0xf9, 0x70, 0x37, 0xf5, 0x5d, 0xdd, 0xb8, 0xa6, 0xa3, 0x59, 0x98, 0x08, 0x92, + 0xcc, 0x15, 0xd7, 0xcb, 0x2b, 0x1b, 0x59, 0x29, 0x7f, 0xf4, 0xfa, 0x8d, 0xe9, 0x31, 0x1f, 0xc5, + 0xdc, 0x96, 0x8d, 0x75, 0xa7, 0x9d, 0x60, 0x7e, 0x75, 0x79, 0x79, 0x71, 0x23, 0x1b, 0x6b, 0x23, + 0xe0, 0x01, 0xfb, 0x21, 0x18, 0x0b, 0x12, 0xac, 0x2c, 0x2e, 0x65, 0xe3, 0x79, 0x74, 0xfd, 0xc6, + 0xf4, 0x88, 0x0f, 0x7b, 0x45, 0x6b, 0xe4, 0x53, 0x1f, 0xf8, 0xec, 0xe4, 0x91, 0x5f, 0xfa, 0xc5, + 0x49, 0x89, 0x68, 0x36, 0x1c, 0x88, 0x11, 0xe8, 0x11, 0x38, 0xbe, 0xbe, 0xb8, 0xb0, 0x52, 0x2e, + 0x55, 0x96, 0xd7, 0x17, 0x2a, 0xec, 0x23, 0x1a, 0xae, 0x76, 0xa3, 0xd7, 0x6f, 0x4c, 0x0f, 0x71, + 0x95, 0xba, 0x61, 0xaf, 0x29, 0xe5, 0x2b, 0xab, 0x1b, 0xe5, 0xac, 0xc4, 0xb0, 0xd7, 0x2c, 0x7c, + 0xd5, 0x70, 0xd8, 0x37, 0xb2, 0x1e, 0x83, 0x13, 0x1d, 0xb0, 0x5d, 0xc5, 0xc6, 0xae, 0xdf, 0x98, + 0x1e, 0x5e, 0xb3, 0x30, 0x9b, 0x3f, 0x94, 0x62, 0x06, 0x72, 0xed, 0x14, 0xab, 0x6b, 0xab, 0xeb, + 0x73, 0x4b, 0xd9, 0xe9, 0x7c, 0xf6, 0xfa, 0x8d, 0xe9, 0x8c, 0x08, 0x86, 0x04, 0xdf, 0xd3, 0xec, + 0x4e, 0xee, 0x78, 0xfe, 0xec, 0x51, 0xb8, 0x8f, 0x97, 0x3c, 0x6d, 0x47, 0xdd, 0xd5, 0xf4, 0xba, + 0x5b, 0x58, 0xe6, 0x6d, 0xbe, 0xf3, 0x39, 0xc6, 0x6b, 0xcb, 0x02, 0xda, 0xb3, 0xbc, 0x9c, 0xef, + 0xfe, 0xe6, 0x28, 0x1f, 0x51, 0x3d, 0x8d, 0xde, 0x3a, 0x75, 0x7f, 0x15, 0x91, 0x8f, 0x28, 0x90, + 0xe7, 0x7b, 0x6e, 0xee, 0xe4, 0x0f, 0x4a, 0x30, 0x72, 0x49, 0xb3, 0x1d, 0xc3, 0xd2, 0xaa, 0x6a, + 0x83, 0xde, 0x20, 0x39, 0xd7, 0x6f, 0x6c, 0x0d, 0x4d, 0xf5, 0x67, 0x61, 0xe0, 0xaa, 0xda, 0x60, + 0x41, 0x2d, 0x4e, 0xbf, 0x78, 0xd1, 0xd9, 0x7c, 0x5e, 0x68, 0x13, 0x0c, 0x18, 0x99, 0xfc, 0x2b, + 0x31, 0x18, 0xa5, 0x93, 0xc1, 0x66, 0x9f, 0x38, 0x22, 0x7b, 0xac, 0x22, 0x24, 0x2c, 0xd5, 0xe1, + 0x45, 0xc1, 0xe2, 0x0c, 0x2f, 0x74, 0x3f, 0x10, 0x5d, 0xbc, 0x9e, 0x29, 0xe1, 0xaa, 0x42, 0x69, + 0xd1, 0x3b, 0x20, 0xd5, 0x54, 0xf7, 0x2a, 0x94, 0x0f, 0xdb, 0xb9, 0xcc, 0x1d, 0x8c, 0xcf, 0xad, + 0x9b, 0x53, 0xa3, 0xfb, 0x6a, 0xb3, 0x51, 0x90, 0x05, 0x1f, 0x59, 0x19, 0x6c, 0xaa, 0x7b, 0x44, + 0x44, 0x64, 0xc2, 0x28, 0x81, 0x56, 0x77, 0x54, 0xbd, 0x8e, 0x59, 0x27, 0xb4, 0xc4, 0x59, 0xbc, + 0x74, 0xe0, 0x4e, 0x8e, 0x79, 0x9d, 0xf8, 0xd8, 0xc9, 0xca, 0x70, 0x53, 0xdd, 0x9b, 0xa7, 0x00, + 0xd2, 0x63, 0x21, 0xf5, 0xb1, 0x4f, 0x4f, 0x1d, 0xa1, 0x2f, 0x0f, 0xbe, 0x29, 0x01, 0x78, 0x16, + 0x43, 0xef, 0x80, 0x6c, 0xd5, 0x6d, 0x51, 0x5a, 0x9b, 0x8f, 0xe1, 0x83, 0xdd, 0xc6, 0x22, 0x64, + 0x6f, 0xb6, 0x36, 0x7f, 0xe3, 0xe6, 0x94, 0xa4, 0x8c, 0x56, 0x43, 0x43, 0xf1, 0x76, 0x18, 0x6a, + 0x99, 0x35, 0xd5, 0xc1, 0x15, 0xba, 0x8f, 0x8b, 0x45, 0xae, 0xf3, 0x93, 0x84, 0xd7, 0xad, 0x9b, + 0x53, 0x88, 0xa9, 0xe5, 0x23, 0x96, 0xe9, 0xea, 0x0f, 0x0c, 0x42, 0x08, 0x7c, 0x3a, 0x7d, 0x4d, + 0x82, 0xa1, 0x92, 0xef, 0x24, 0x57, 0x0e, 0x06, 0x9b, 0x86, 0xae, 0xed, 0x72, 0x7f, 0x4c, 0x2b, + 0xa2, 0x89, 0xf2, 0x90, 0x62, 0x97, 0xea, 0x9c, 0x7d, 0x51, 0xea, 0x14, 0x6d, 0x42, 0x75, 0x0d, + 0x6f, 0xd9, 0x9a, 0x18, 0x0d, 0x45, 0x34, 0xd1, 0x45, 0xc8, 0xda, 0xb8, 0xda, 0xb2, 0x34, 0x67, + 0xbf, 0x52, 0x35, 0x74, 0x47, 0xad, 0x3a, 0xec, 0x7a, 0x56, 0xf1, 0xae, 0x5b, 0x37, 0xa7, 0x8e, + 0x33, 0x59, 0xc3, 0x18, 0xb2, 0x32, 0x2a, 0x40, 0xf3, 0x0c, 0x42, 0x7a, 0xa8, 0x61, 0x47, 0xd5, + 0x1a, 0x76, 0x8e, 0xbd, 0x07, 0x13, 0x4d, 0x9f, 0x2e, 0x5f, 0x18, 0xf4, 0x17, 0xb6, 0x2e, 0x42, + 0xd6, 0x30, 0xb1, 0x15, 0x48, 0x44, 0xa5, 0x70, 0xcf, 0x61, 0x0c, 0x59, 0x19, 0x15, 0x20, 0x91, + 0xa4, 0x3a, 0x64, 0x98, 0xc5, 0x46, 0xd1, 0x6c, 0x6d, 0x79, 0xf5, 0xb0, 0x89, 0xb6, 0xd1, 0x98, + 0xd3, 0xf7, 0x8b, 0x4f, 0x78, 0xdc, 0xc3, 0x74, 0xf2, 0xd7, 0xbf, 0xf4, 0xe8, 0x04, 0x77, 0x0d, + 0xaf, 0x3e, 0x75, 0x19, 0xef, 0x93, 0xe1, 0xe7, 0xa8, 0x6b, 0x14, 0x93, 0xa4, 0x9d, 0x2f, 0xaa, + 0x5a, 0x43, 0x5c, 0x33, 0x56, 0x78, 0x0b, 0x15, 0x60, 0xc0, 0x76, 0x54, 0xa7, 0x65, 0xf3, 0x8f, + 0x7a, 0xc9, 0xdd, 0x5c, 0xad, 0x68, 0xe8, 0xb5, 0x75, 0x8a, 0xa9, 0x70, 0x0a, 0x74, 0x11, 0x06, + 0x1c, 0x63, 0x17, 0xeb, 0xdc, 0x84, 0x07, 0x9a, 0xdf, 0xf4, 0xb5, 0x1c, 0xa3, 0x26, 0x16, 0xa9, + 0xe1, 0x06, 0xae, 0xb3, 0xb4, 0x6a, 0x47, 0x25, 0xbb, 0x0f, 0xfa, 0x6d, 0xaf, 0xe2, 0xe2, 0x81, + 0x27, 0x21, 0xb7, 0x54, 0x98, 0x9f, 0xac, 0x8c, 0xba, 0xa0, 0x75, 0x0a, 0x41, 0x97, 0x03, 0x47, + 0x0e, 0xf9, 0x07, 0xf0, 0xee, 0xed, 0xa6, 0xbe, 0xcf, 0xa7, 0x45, 0x7d, 0xc2, 0x7f, 0x60, 0xf1, + 0x22, 0x64, 0x5b, 0xfa, 0x96, 0xa1, 0xd3, 0xbb, 0x80, 0x3c, 0xbf, 0x27, 0xfb, 0xbb, 0xb8, 0xdf, + 0x39, 0xc2, 0x18, 0xb2, 0x32, 0xea, 0x82, 0x2e, 0xb1, 0x5d, 0x40, 0x0d, 0x46, 0x3c, 0x2c, 0x3a, + 0x51, 0xd3, 0x91, 0x13, 0xf5, 0x1e, 0x3e, 0x51, 0x8f, 0x86, 0x7b, 0xf1, 0xe6, 0xea, 0xb0, 0x0b, + 0x24, 0x64, 0xe8, 0x12, 0x80, 0x17, 0x1e, 0x68, 0x9d, 0x62, 0xa8, 0xfb, 0xc0, 0x7b, 0x31, 0x46, + 0xec, 0xf7, 0x3c, 0x5a, 0xf4, 0x2e, 0x18, 0x6f, 0x6a, 0x7a, 0xc5, 0xc6, 0x8d, 0xed, 0x0a, 0x37, + 0x30, 0x61, 0x49, 0xbf, 0xe5, 0x52, 0x5c, 0x3a, 0x98, 0x3f, 0xdc, 0xba, 0x39, 0x95, 0xe7, 0x21, + 0xb4, 0x9d, 0xa5, 0xac, 0x8c, 0x35, 0x35, 0x7d, 0x1d, 0x37, 0xb6, 0x4b, 0x2e, 0xac, 0x90, 0xf9, + 0xc0, 0xa7, 0xa7, 0x8e, 0xf0, 0xe9, 0x7a, 0x44, 0x3e, 0x47, 0x6b, 0xe7, 0x7c, 0x9a, 0x61, 0x9b, + 0xec, 0x49, 0x54, 0xd1, 0xa0, 0x15, 0x8d, 0xb4, 0xe2, 0x01, 0xd8, 0x34, 0x7f, 0xe5, 0x3f, 0x4d, + 0x4b, 0xf2, 0x17, 0x24, 0x18, 0x28, 0x5d, 0x59, 0x53, 0x35, 0x0b, 0x2d, 0xc2, 0x98, 0xe7, 0x39, + 0xc1, 0x49, 0x7e, 0xf2, 0xd6, 0xcd, 0xa9, 0x5c, 0xd8, 0xb9, 0xdc, 0x59, 0xee, 0x39, 0xb0, 0x98, + 0xe6, 0x8b, 0xdd, 0x36, 0xae, 0x01, 0x56, 0x6d, 0x28, 0x72, 0xfb, 0xb6, 0x36, 0xa4, 0x66, 0x19, + 0x06, 0x99, 0xb4, 0x36, 0x2a, 0x40, 0xd2, 0x24, 0x3f, 0xf8, 0x8b, 0x81, 0xc9, 0xae, 0xce, 0x4b, + 0xf1, 0xdd, 0x42, 0x26, 0x21, 0x91, 0x3f, 0x12, 0x03, 0x28, 0x5d, 0xb9, 0xb2, 0x61, 0x69, 0x66, + 0x03, 0x3b, 0xb7, 0x53, 0xf3, 0x0d, 0x38, 0xea, 0xdb, 0x25, 0x59, 0xd5, 0x90, 0xf6, 0xd3, 0xb7, + 0x6e, 0x4e, 0x9d, 0x0c, 0x6b, 0xef, 0x43, 0x93, 0x95, 0x71, 0x6f, 0xbf, 0x64, 0x55, 0x3b, 0x72, + 0xad, 0xd9, 0x8e, 0xcb, 0x35, 0xde, 0x9d, 0xab, 0x0f, 0xcd, 0xcf, 0xb5, 0x64, 0x3b, 0x9d, 0x4d, + 0xbb, 0x0e, 0x43, 0x9e, 0x49, 0x6c, 0x54, 0x82, 0x94, 0xc3, 0x7f, 0x73, 0x0b, 0xcb, 0xdd, 0x2d, + 0x2c, 0xc8, 0xb8, 0x95, 0x5d, 0x4a, 0xf9, 0x2f, 0x24, 0x00, 0xcf, 0x67, 0x7f, 0x3c, 0x5d, 0x8c, + 0x84, 0x72, 0x1e, 0x78, 0xe3, 0x87, 0x4a, 0xd5, 0x38, 0x75, 0xc8, 0x9e, 0x3f, 0x1d, 0x83, 0xf1, + 0x4d, 0x11, 0x79, 0x7e, 0xec, 0x6d, 0xb0, 0x06, 0x83, 0x58, 0x77, 0x2c, 0x8d, 0x1a, 0x81, 0x8c, + 0xf6, 0x63, 0xdd, 0x46, 0xbb, 0x83, 0x4e, 0xf4, 0x63, 0x36, 0xa2, 0xe8, 0xce, 0xd9, 0x84, 0xac, + 0xf1, 0xa1, 0x38, 0xe4, 0xba, 0x51, 0xa2, 0x79, 0x18, 0xad, 0x5a, 0x98, 0x02, 0x2a, 0xfe, 0xca, + 0x5f, 0x31, 0xef, 0x65, 0x96, 0x21, 0x04, 0x59, 0x19, 0x11, 0x10, 0xbe, 0x7a, 0xd4, 0x81, 0xa4, + 0x7d, 0xc4, 0xed, 0x08, 0x56, 0x9f, 0x79, 0x9e, 0xcc, 0x97, 0x0f, 0xd1, 0x49, 0x90, 0x01, 0x5b, + 0x3f, 0x46, 0x3c, 0x28, 0x5d, 0x40, 0x5e, 0x82, 0x51, 0x4d, 0xd7, 0x1c, 0x4d, 0x6d, 0x54, 0xb6, + 0xd4, 0x86, 0xaa, 0x57, 0x0f, 0x93, 0x35, 0xb3, 0x90, 0xcf, 0xbb, 0x0d, 0xb1, 0x93, 0x95, 0x11, + 0x0e, 0x29, 0x32, 0x00, 0xba, 0x04, 0x83, 0xa2, 0xab, 0xc4, 0xa1, 0xb2, 0x0d, 0x41, 0xee, 0x4b, + 0xf0, 0x7e, 0x26, 0x0e, 0x63, 0x0a, 0xae, 0xfd, 0xff, 0xa1, 0x38, 0xd8, 0x50, 0x2c, 0x03, 0xb0, + 0xe9, 0x4e, 0x02, 0xec, 0x21, 0x46, 0x83, 0x04, 0x8c, 0x34, 0xe3, 0x50, 0xb2, 0x1d, 0xdf, 0x78, + 0xdc, 0x8c, 0x41, 0xc6, 0x3f, 0x1e, 0x7f, 0x45, 0x57, 0x25, 0xb4, 0xe8, 0x45, 0xa2, 0x04, 0xff, + 0x06, 0x68, 0x97, 0x48, 0xd4, 0xe6, 0xbd, 0xbd, 0x43, 0xd0, 0xff, 0x8c, 0xc1, 0xc0, 0x9a, 0x6a, + 0xa9, 0x4d, 0x1b, 0x55, 0xdb, 0x32, 0x4d, 0x51, 0x7e, 0x6c, 0xfb, 0x80, 0x33, 0xaf, 0x76, 0x44, + 0x24, 0x9a, 0x1f, 0xeb, 0x90, 0x68, 0xfe, 0x04, 0x8c, 0x90, 0xed, 0xb0, 0xef, 0x08, 0x03, 0xb1, + 0xf6, 0x70, 0xf1, 0x84, 0xc7, 0x25, 0xf8, 0x9c, 0xed, 0x96, 0xaf, 0xf8, 0xcf, 0x30, 0x0c, 0x11, + 0x0c, 0x2f, 0x30, 0x13, 0xf2, 0x63, 0xde, 0xb6, 0xd4, 0xf7, 0x50, 0x56, 0xa0, 0xa9, 0xee, 0x95, + 0x59, 0x03, 0x2d, 0x01, 0xda, 0x71, 0x2b, 0x23, 0x15, 0xcf, 0x9c, 0x84, 0xfe, 0xee, 0x5b, 0x37, + 0xa7, 0x4e, 0x30, 0xfa, 0x76, 0x1c, 0x59, 0x19, 0xf3, 0x80, 0x82, 0xdb, 0x93, 0x00, 0x44, 0xaf, + 0x0a, 0x3b, 0x2d, 0xc8, 0xb6, 0x3b, 0x47, 0x6f, 0xdd, 0x9c, 0x1a, 0x63, 0x5c, 0xbc, 0x67, 0xb2, + 0x92, 0x26, 0x8d, 0x12, 0xf9, 0xed, 0xf3, 0xec, 0xcf, 0x4a, 0x80, 0xbc, 0x90, 0xaf, 0x60, 0xdb, + 0x24, 0xfb, 0x33, 0x92, 0x88, 0xfb, 0xb2, 0x66, 0xa9, 0x77, 0x22, 0xee, 0xd1, 0x8b, 0x44, 0xdc, + 0x37, 0x53, 0x9e, 0xf6, 0xc2, 0x63, 0x8c, 0x8f, 0x63, 0x87, 0xa3, 0x95, 0x33, 0xf3, 0x86, 0x26, + 0xa8, 0xdb, 0xe2, 0xe1, 0x11, 0xf9, 0xdf, 0x48, 0x70, 0xa2, 0xcd, 0xa3, 0x5c, 0x61, 0xff, 0x1a, + 0x20, 0xcb, 0xf7, 0x90, 0x7f, 0xcf, 0x8d, 0x09, 0x7d, 0x60, 0x07, 0x1d, 0xb3, 0xda, 0xe2, 0xee, + 0xed, 0x8b, 0xf0, 0xec, 0x6c, 0xe6, 0xbf, 0x90, 0x60, 0xc2, 0xdf, 0xbd, 0xab, 0xc8, 0x0a, 0x64, + 0xfc, 0xbd, 0x73, 0x15, 0xee, 0xeb, 0x47, 0x05, 0x2e, 0x7d, 0x80, 0x1e, 0x3d, 0xef, 0x4d, 0x57, + 0x56, 0x3b, 0x7b, 0xbc, 0x6f, 0x6b, 0x08, 0x99, 0xc2, 0xd3, 0x36, 0x41, 0xc7, 0xe3, 0xff, 0x48, + 0x90, 0x58, 0x33, 0x8c, 0x06, 0x32, 0x60, 0x4c, 0x37, 0x9c, 0x0a, 0xf1, 0x2c, 0x5c, 0xab, 0xf0, + 0x4d, 0x37, 0x8b, 0x83, 0xf3, 0x07, 0x33, 0xd2, 0x77, 0x6e, 0x4e, 0xb5, 0xb3, 0x52, 0x46, 0x75, + 0xc3, 0x29, 0x52, 0xc8, 0x06, 0xdb, 0x92, 0xbf, 0x0b, 0x86, 0x83, 0x9d, 0xb1, 0x28, 0xf9, 0xc2, + 0x81, 0x3b, 0x0b, 0xb2, 0xb9, 0x75, 0x73, 0x6a, 0xc2, 0x9b, 0x31, 0x2e, 0x58, 0x56, 0x32, 0x5b, + 0xbe, 0xde, 0xd9, 0xf1, 0xae, 0xef, 0x7d, 0x7a, 0x4a, 0x3a, 0xfd, 0x65, 0x09, 0xc0, 0xab, 0x3c, + 0xa0, 0x47, 0xe0, 0x78, 0x71, 0x75, 0xa5, 0x54, 0x59, 0xdf, 0x98, 0xdb, 0xd8, 0x5c, 0xaf, 0x6c, + 0xae, 0xac, 0xaf, 0x95, 0xe7, 0x17, 0x2f, 0x2e, 0x96, 0x4b, 0x5e, 0x79, 0xdc, 0x36, 0x71, 0x55, + 0xdb, 0xd6, 0x70, 0x0d, 0x3d, 0x00, 0x13, 0x41, 0x6c, 0xd2, 0x2a, 0x97, 0xb2, 0x52, 0x3e, 0x73, + 0xfd, 0xc6, 0x74, 0x8a, 0xe5, 0x62, 0xb8, 0x86, 0x4e, 0xc1, 0xd1, 0x76, 0xbc, 0xc5, 0x95, 0x85, + 0x6c, 0x2c, 0x3f, 0x7c, 0xfd, 0xc6, 0x74, 0xda, 0x4d, 0xda, 0x90, 0x0c, 0xc8, 0x8f, 0xc9, 0xf9, + 0xc5, 0xf3, 0x70, 0xfd, 0xc6, 0xf4, 0x00, 0x33, 0x60, 0x3e, 0xf1, 0x81, 0xcf, 0x4e, 0x1e, 0x29, + 0x5e, 0xec, 0x5a, 0x00, 0x7f, 0xa4, 0xa7, 0xed, 0xf6, 0xdc, 0xa2, 0x76, 0xb0, 0xea, 0x7d, 0xfd, + 0x38, 0x4c, 0x75, 0xa9, 0x7a, 0x3b, 0x7b, 0x11, 0x05, 0xef, 0x1e, 0xa5, 0xed, 0xc8, 0xd2, 0x75, + 0x97, 0x62, 0xf9, 0xe1, 0x0b, 0xda, 0x7d, 0xd5, 0xee, 0xe5, 0x7f, 0x9b, 0x00, 0xb4, 0x6c, 0xd7, + 0xe7, 0x49, 0x52, 0xe5, 0x3b, 0xa2, 0x15, 0xaa, 0xd9, 0x48, 0x3f, 0x54, 0xcd, 0x66, 0x39, 0x50, + 0x05, 0x89, 0x1d, 0xac, 0xd2, 0xda, 0x77, 0x29, 0x24, 0xfe, 0x23, 0x29, 0x85, 0x74, 0xce, 0x94, + 0x12, 0xb7, 0x6f, 0x4b, 0x95, 0x3c, 0xec, 0xb6, 0x92, 0x57, 0x38, 0x07, 0x7a, 0x54, 0x38, 0x73, + 0x5d, 0xcb, 0x98, 0x9c, 0x1a, 0x9d, 0x15, 0x57, 0x6e, 0x06, 0xfb, 0x5b, 0xdb, 0xf8, 0x9d, 0x9c, + 0xd4, 0x07, 0xc4, 0xca, 0x76, 0x12, 0xf2, 0xed, 0xee, 0x24, 0x82, 0xaf, 0xfc, 0xd1, 0x38, 0x64, + 0x97, 0xed, 0x7a, 0xb9, 0xa6, 0x39, 0x77, 0xc8, 0xd7, 0x9e, 0xed, 0xbe, 0x4d, 0x45, 0xb7, 0x6e, + 0x4e, 0x8d, 0x30, 0x9b, 0xf6, 0xb0, 0x64, 0x13, 0x46, 0x43, 0x2f, 0x07, 0xb8, 0x67, 0x95, 0x0e, + 0xf3, 0x8e, 0x22, 0xc4, 0x4a, 0xa6, 0xbb, 0x0a, 0x9f, 0x7f, 0xa3, 0xbd, 0xce, 0xce, 0xcc, 0x1c, + 0xea, 0xd2, 0x9d, 0xac, 0xe9, 0x79, 0x63, 0x96, 0x87, 0x5c, 0x78, 0x50, 0xdc, 0x11, 0xfb, 0x63, + 0x09, 0x86, 0x96, 0x6d, 0xb1, 0x8b, 0xc6, 0x3f, 0xa6, 0x15, 0x85, 0xa7, 0xdc, 0x8b, 0x24, 0xf1, + 0xfe, 0xfc, 0x56, 0x5c, 0x2e, 0xf1, 0x8c, 0x70, 0x14, 0xc6, 0x7d, 0x7a, 0xba, 0xfa, 0xff, 0x4e, + 0x8c, 0xc6, 0xc7, 0x22, 0xae, 0x6b, 0xba, 0x9b, 0x54, 0xe0, 0xbf, 0xaa, 0xfb, 0x25, 0xcf, 0xce, + 0x89, 0xc3, 0xda, 0x79, 0x97, 0x06, 0x88, 0x90, 0x3d, 0xdd, 0x8c, 0x71, 0xb9, 0x7d, 0x37, 0x2f, + 0x1d, 0xe0, 0xa0, 0x4c, 0x68, 0xcf, 0x2e, 0xbf, 0x2e, 0xc1, 0xf0, 0xb2, 0x5d, 0xdf, 0xd4, 0x6b, + 0xff, 0xcf, 0xfb, 0xef, 0x36, 0x1c, 0x0d, 0x68, 0x7a, 0x87, 0x4c, 0x7a, 0xe6, 0xd5, 0x04, 0xc4, + 0x97, 0xed, 0x3a, 0x7a, 0x09, 0x46, 0xc3, 0x49, 0xc3, 0xe9, 0x6e, 0x31, 0xbb, 0x7d, 0x45, 0xc8, + 0x9f, 0xe9, 0x1f, 0xd7, 0xd5, 0x64, 0x17, 0x86, 0x83, 0x2b, 0xc7, 0xa9, 0x1e, 0x4c, 0x02, 0x98, + 0xf9, 0xc7, 0xfa, 0xc5, 0x74, 0x3b, 0x7b, 0x07, 0xa4, 0xdc, 0xa0, 0x77, 0x6f, 0x0f, 0x6a, 0x81, + 0x94, 0x7f, 0xb8, 0x0f, 0x24, 0x97, 0xfb, 0x4b, 0x30, 0x1a, 0x0e, 0x29, 0xbd, 0xac, 0x17, 0xc2, + 0xed, 0x69, 0xbd, 0x6e, 0x53, 0x6b, 0x0b, 0xc0, 0x37, 0x0f, 0xee, 0xef, 0xc1, 0xc1, 0x43, 0xcb, + 0x3f, 0xda, 0x17, 0x9a, 0xbb, 0xb9, 0xba, 0xdd, 0xc9, 0xf8, 0xbf, 0x8a, 0xc1, 0x69, 0x7f, 0x9a, + 0xfb, 0x52, 0x0b, 0x5b, 0xfb, 0x6e, 0x26, 0x6b, 0xaa, 0x75, 0x4d, 0xf7, 0xdf, 0xae, 0x3b, 0xe1, + 0x9f, 0x35, 0x14, 0x57, 0xc8, 0x2b, 0xeb, 0x30, 0xb4, 0xa6, 0xd6, 0xb1, 0x82, 0x5f, 0x6a, 0x61, + 0xdb, 0xe9, 0x70, 0xbb, 0xeb, 0x18, 0x0c, 0x18, 0xdb, 0xdb, 0xe2, 0xac, 0x59, 0x42, 0xe1, 0x2d, + 0x34, 0x01, 0xc9, 0x86, 0xd6, 0xd4, 0xd8, 0xcc, 0x4c, 0x28, 0xac, 0x81, 0xa6, 0x60, 0xa8, 0x4a, + 0x26, 0x60, 0x85, 0x9d, 0x9b, 0x4f, 0x88, 0x2f, 0x2f, 0xb5, 0x74, 0x67, 0x83, 0x40, 0xe4, 0x67, + 0x21, 0xc3, 0xfa, 0xe3, 0xd6, 0x3f, 0x01, 0x29, 0x7a, 0xce, 0xd9, 0xeb, 0x75, 0x90, 0xb4, 0x2f, + 0xb3, 0x9b, 0x60, 0x8c, 0x0b, 0xeb, 0x98, 0x35, 0x8a, 0xc5, 0xae, 0xa6, 0x3c, 0x15, 0x9d, 0x11, + 0x30, 0x43, 0xb9, 0x66, 0xfc, 0xad, 0x24, 0x1c, 0xe5, 0xfb, 0x0f, 0xd5, 0xd4, 0x66, 0x77, 0x1c, + 0x47, 0xdc, 0x56, 0x06, 0x1e, 0x02, 0x54, 0x53, 0x93, 0xf7, 0x21, 0x71, 0xc9, 0x71, 0x4c, 0x74, + 0x1a, 0x92, 0x56, 0xab, 0x81, 0xc5, 0xab, 0x18, 0x37, 0x95, 0x54, 0x4d, 0x6d, 0x86, 0x20, 0x28, + 0xad, 0x06, 0x56, 0x18, 0x0a, 0x2a, 0xc3, 0xd4, 0x76, 0xab, 0xd1, 0xd8, 0xaf, 0xd4, 0x30, 0xfd, + 0x67, 0x78, 0xee, 0xff, 0x9d, 0xc1, 0x7b, 0xa6, 0xaa, 0xbb, 0xf9, 0x7e, 0x4a, 0x39, 0x49, 0xd1, + 0x4a, 0x14, 0x4b, 0xfc, 0xcf, 0x99, 0xb2, 0xc0, 0x91, 0x7f, 0x3f, 0x06, 0x29, 0xc1, 0x9a, 0x5e, + 0xcd, 0xc2, 0x0d, 0x5c, 0x75, 0x0c, 0x71, 0x94, 0xc1, 0x6d, 0x23, 0x04, 0xf1, 0x3a, 0x1f, 0xa2, + 0xf4, 0xa5, 0x23, 0x0a, 0x69, 0x10, 0x98, 0x7b, 0x61, 0x8e, 0xc0, 0xcc, 0x16, 0x19, 0xb5, 0x84, + 0x69, 0x88, 0x9a, 0xe9, 0xa5, 0x23, 0x0a, 0x6d, 0xa1, 0x1c, 0x0c, 0x10, 0x97, 0x75, 0xd8, 0x17, + 0x81, 0x09, 0x9c, 0xb7, 0xd1, 0x31, 0x48, 0x9a, 0xaa, 0x53, 0x65, 0x67, 0xdd, 0xc9, 0x03, 0xd6, + 0x24, 0x81, 0x99, 0x7d, 0x89, 0x21, 0xfc, 0x9f, 0xa6, 0x88, 0x31, 0xd8, 0x27, 0x2f, 0x89, 0xdc, + 0x6b, 0xaa, 0xe3, 0x60, 0x4b, 0x27, 0x0c, 0x19, 0x3a, 0x42, 0x90, 0xd8, 0x32, 0x6a, 0xfb, 0xfc, + 0xbf, 0x5f, 0xd1, 0xdf, 0xfc, 0xff, 0xf2, 0x50, 0x7f, 0xa8, 0xd0, 0x87, 0xec, 0x9f, 0xfe, 0x65, + 0x04, 0xb0, 0x48, 0x90, 0xca, 0x30, 0xae, 0xd6, 0x6a, 0x1a, 0xf1, 0x6a, 0xb5, 0x51, 0xd9, 0xd2, + 0xe8, 0x7e, 0xd8, 0xa6, 0xff, 0xd2, 0xb1, 0xdb, 0x58, 0x20, 0x8f, 0xa0, 0xc8, 0xf1, 0x8b, 0x69, + 0x18, 0x34, 0x99, 0x50, 0xf2, 0x05, 0x18, 0x6b, 0x93, 0x94, 0xc8, 0xb7, 0xab, 0xe9, 0x35, 0x71, + 0x8b, 0x90, 0xfc, 0x26, 0x30, 0xfa, 0xd9, 0x5a, 0x76, 0x48, 0x84, 0xfe, 0x2e, 0xbe, 0xa7, 0xfb, + 0x1d, 0xd3, 0x11, 0xdf, 0x1d, 0x53, 0xd5, 0xd4, 0x8a, 0x69, 0xca, 0x9f, 0x5f, 0x2d, 0x9d, 0xe3, + 0x0f, 0xd8, 0xb5, 0xd2, 0x19, 0xc3, 0xaa, 0xcf, 0xd6, 0xb1, 0x2e, 0xf6, 0xb7, 0xe4, 0x91, 0x6a, + 0x6a, 0x36, 0x75, 0x47, 0xef, 0x33, 0xba, 0xf6, 0x05, 0xdf, 0x6f, 0x7a, 0xe3, 0x34, 0xb1, 0x30, + 0xb7, 0xb6, 0xe8, 0xfa, 0xf1, 0x6f, 0xc6, 0xe0, 0xa4, 0xcf, 0x8f, 0x7d, 0xc8, 0xed, 0xee, 0x9c, + 0xef, 0xec, 0xf1, 0x7d, 0x5c, 0x42, 0xbf, 0x0c, 0x09, 0x82, 0x8f, 0x22, 0xfe, 0x6b, 0x4e, 0xee, + 0x57, 0xbf, 0xfe, 0xcf, 0xe5, 0xe0, 0x66, 0x2b, 0x30, 0x2a, 0x94, 0x49, 0xf1, 0xfd, 0xfd, 0xdb, + 0x2f, 0xeb, 0x7d, 0x41, 0xd8, 0xbe, 0x7d, 0x66, 0x0c, 0xdb, 0xf0, 0xdb, 0x67, 0x41, 0xee, 0x52, + 0x19, 0x60, 0x11, 0xb3, 0x77, 0x89, 0xe3, 0x00, 0xe1, 0xb8, 0xdb, 0xc5, 0xbc, 0x5e, 0x23, 0xd8, + 0x67, 0xd5, 0x62, 0x0f, 0x8e, 0x3d, 0x4f, 0xfa, 0xf6, 0xea, 0xd7, 0x22, 0xb0, 0x1f, 0x73, 0x8f, + 0xd9, 0x48, 0xfc, 0x3f, 0x6a, 0x8a, 0x23, 0x34, 0xe0, 0xc9, 0xc7, 0x6b, 0x10, 0x0f, 0xcc, 0x74, + 0x5d, 0x2f, 0x66, 0x7c, 0x8b, 0x85, 0xe2, 0xa3, 0x94, 0x7f, 0x59, 0x82, 0xe3, 0x6d, 0x5d, 0xf3, + 0x18, 0xbf, 0xd0, 0xe1, 0x0e, 0x61, 0xdf, 0xa7, 0xfb, 0xfc, 0xf7, 0x09, 0x17, 0x3a, 0x08, 0xfb, + 0x60, 0xa4, 0xb0, 0x4c, 0x8a, 0x80, 0xb4, 0xcf, 0xc0, 0xd1, 0xa0, 0xb0, 0xc2, 0x4c, 0xf7, 0xc3, + 0x48, 0x30, 0x31, 0xe5, 0xe6, 0x1a, 0x0e, 0xa4, 0xa6, 0x72, 0x25, 0x6c, 0x67, 0x57, 0xd7, 0x32, + 0xa4, 0x5d, 0x54, 0x9e, 0x4f, 0xf6, 0xad, 0xaa, 0x47, 0x29, 0x7f, 0x44, 0x82, 0xe9, 0x60, 0x0f, + 0xde, 0x0e, 0xd5, 0x3e, 0x98, 0xb0, 0xb7, 0x6d, 0x88, 0x5f, 0x97, 0xe0, 0x9e, 0x1e, 0x32, 0x71, + 0x03, 0xbc, 0x0c, 0x13, 0xbe, 0x12, 0xbd, 0x08, 0xe1, 0x62, 0xd8, 0x4f, 0x47, 0xbf, 0x5b, 0x70, + 0x93, 0xa6, 0xbb, 0x88, 0x51, 0x3e, 0xff, 0x87, 0x53, 0xe3, 0xed, 0xcf, 0x6c, 0x65, 0xbc, 0xbd, + 0xac, 0x7e, 0x1b, 0xfd, 0xe3, 0x55, 0x09, 0x1e, 0x0a, 0xaa, 0xda, 0xe1, 0xbd, 0xf9, 0x1b, 0x35, + 0x0e, 0xff, 0x51, 0x82, 0xd3, 0xfd, 0x08, 0xe7, 0xe6, 0xb7, 0xe3, 0xde, 0x8b, 0xb2, 0xf0, 0x78, + 0x3c, 0x7c, 0x80, 0x13, 0x06, 0xdc, 0x4b, 0x91, 0xcb, 0xed, 0x0e, 0x18, 0xde, 0xe4, 0x13, 0xcb, + 0x3f, 0xe4, 0xae, 0x91, 0x83, 0xbb, 0x4f, 0x61, 0xe4, 0xc0, 0xfe, 0xb3, 0xc3, 0x58, 0xc4, 0x3a, + 0x8c, 0x85, 0x6f, 0x7f, 0x78, 0x95, 0xc7, 0xad, 0x0e, 0x2f, 0xc7, 0xde, 0x0e, 0xe3, 0x1d, 0x5c, + 0x99, 0xcf, 0xea, 0x03, 0x78, 0xb2, 0x82, 0xda, 0x9d, 0x55, 0xde, 0x87, 0x29, 0xda, 0x6f, 0x07, + 0x43, 0xdf, 0x69, 0x95, 0x9b, 0x3c, 0xb6, 0x74, 0xec, 0x9a, 0xeb, 0xbe, 0x08, 0x03, 0x6c, 0x9c, + 0xb9, 0xba, 0x87, 0x70, 0x14, 0xce, 0x40, 0xfe, 0x84, 0x88, 0x65, 0x25, 0x21, 0x76, 0xe7, 0x39, + 0xd4, 0x8f, 0xae, 0xb7, 0x69, 0x0e, 0xf9, 0x8c, 0xf1, 0x4d, 0x11, 0xd5, 0x3a, 0x4b, 0xc7, 0xcd, + 0x51, 0xbd, 0x6d, 0x51, 0x8d, 0xd9, 0xe6, 0xce, 0x86, 0xaf, 0x5f, 0x14, 0xe1, 0xcb, 0xd5, 0x29, + 0x22, 0x7c, 0xbd, 0x31, 0xa6, 0x77, 0x03, 0x59, 0x84, 0x98, 0x7f, 0x19, 0x03, 0xd9, 0xf7, 0x24, + 0x38, 0x41, 0x75, 0xf3, 0xbf, 0x71, 0x3d, 0xa8, 0xc9, 0x1f, 0x01, 0x64, 0x5b, 0xd5, 0x4a, 0xc7, + 0xd9, 0x9d, 0xb5, 0xad, 0xea, 0x95, 0xc0, 0xfa, 0xf2, 0x08, 0xa0, 0x9a, 0xed, 0x84, 0xb1, 0xd9, + 0xf1, 0xf5, 0x6c, 0xcd, 0x76, 0xae, 0xf4, 0x58, 0x8d, 0x12, 0xb7, 0x61, 0x38, 0xbf, 0x21, 0x41, + 0xbe, 0x93, 0xca, 0x7c, 0xf8, 0x34, 0x38, 0x16, 0x78, 0x7b, 0x1f, 0x1e, 0xc1, 0x47, 0xfa, 0x79, + 0x67, 0x1d, 0x9a, 0x46, 0x47, 0x2d, 0x7c, 0xa7, 0xf3, 0x80, 0xa9, 0xa0, 0x87, 0xb6, 0x67, 0xd6, + 0x6f, 0xd8, 0xf4, 0xf9, 0x52, 0x5b, 0x5c, 0xfd, 0x4b, 0x91, 0x7b, 0xef, 0xc1, 0x64, 0x17, 0xa9, + 0xef, 0xf4, 0xba, 0xb7, 0xd3, 0x75, 0x30, 0x6f, 0x77, 0xfa, 0xfe, 0x24, 0x9f, 0x09, 0xc1, 0xab, + 0x51, 0xbe, 0xbd, 0x58, 0xa7, 0xbb, 0xd5, 0xf2, 0x5b, 0xe1, 0xae, 0x8e, 0x54, 0x5c, 0xb6, 0x02, + 0x24, 0x76, 0x34, 0xdb, 0xe1, 0x62, 0x3d, 0xd0, 0x4d, 0xac, 0x10, 0x35, 0xa5, 0x91, 0x11, 0x64, + 0x29, 0xeb, 0x35, 0xc3, 0x68, 0x70, 0x31, 0xe4, 0xcb, 0x30, 0xe6, 0x83, 0xf1, 0x4e, 0xce, 0x41, + 0xc2, 0x34, 0xf8, 0x77, 0x81, 0x86, 0xce, 0x9c, 0xec, 0xd6, 0x09, 0xa1, 0xe1, 0x6a, 0x53, 0x7c, + 0x79, 0x02, 0x10, 0x63, 0x46, 0x0f, 0x77, 0x89, 0x2e, 0xd6, 0x61, 0x3c, 0x00, 0xe5, 0x9d, 0xbc, + 0x09, 0x06, 0x4c, 0x0a, 0x71, 0x2f, 0xc1, 0x76, 0xeb, 0x86, 0x62, 0xb9, 0x5f, 0x62, 0xa1, 0xad, + 0x33, 0xdf, 0x39, 0x0a, 0x49, 0xca, 0x15, 0x7d, 0x5c, 0x02, 0xf0, 0x1d, 0xd5, 0x9a, 0xe9, 0xc6, + 0xa6, 0xf3, 0x9e, 0x38, 0x3f, 0xdb, 0x37, 0x3e, 0xcf, 0xd9, 0x4e, 0xbf, 0xe7, 0xdf, 0x7d, 0xfb, + 0xa3, 0xb1, 0xfb, 0x90, 0x3c, 0xdb, 0x65, 0x37, 0xee, 0x9b, 0x2f, 0x9f, 0x0b, 0x7c, 0x94, 0xe6, + 0xd1, 0xfe, 0xba, 0x12, 0x92, 0xcd, 0xf4, 0x8b, 0xce, 0x05, 0xbb, 0x40, 0x05, 0x3b, 0x8b, 0x9e, + 0x88, 0x16, 0x6c, 0xf6, 0x9d, 0xc1, 0x49, 0xf3, 0x6e, 0xf4, 0xbb, 0x12, 0x4c, 0x74, 0xda, 0xd2, + 0xa1, 0xf3, 0xfd, 0x49, 0xd1, 0x9e, 0x52, 0xe4, 0x9f, 0x3e, 0x04, 0x25, 0x57, 0x65, 0x81, 0xaa, + 0x32, 0x87, 0x9e, 0x3d, 0x84, 0x2a, 0xb3, 0xbe, 0x75, 0x07, 0xfd, 0x6f, 0x09, 0xee, 0xee, 0xb9, + 0x43, 0x42, 0x73, 0xfd, 0x49, 0xd9, 0x23, 0x77, 0xca, 0x17, 0x7f, 0x18, 0x16, 0x5c, 0xe3, 0xe7, + 0xa9, 0xc6, 0x97, 0xd1, 0xe2, 0x61, 0x34, 0xf6, 0x32, 0x22, 0xbf, 0xee, 0xbf, 0x1d, 0x3c, 0xf2, + 0xdf, 0xdb, 0x9d, 0xda, 0x36, 0x1e, 0x11, 0x13, 0xa3, 0x3d, 0xa9, 0x95, 0xdf, 0x42, 0x55, 0x50, + 0xd0, 0xda, 0x0f, 0x39, 0x68, 0xb3, 0xef, 0x0c, 0x06, 0xfe, 0x77, 0xa3, 0xff, 0x25, 0x75, 0x3e, + 0xc1, 0xff, 0x54, 0x4f, 0x11, 0xbb, 0x6f, 0xaa, 0xf2, 0xe7, 0x0f, 0x4e, 0xc8, 0x95, 0x6c, 0x52, + 0x25, 0xeb, 0x08, 0xdf, 0x6e, 0x25, 0x3b, 0x0e, 0x22, 0xfa, 0x9a, 0x04, 0x13, 0x9d, 0xf6, 0x24, + 0x11, 0xd3, 0xb2, 0xc7, 0x26, 0x2b, 0x62, 0x5a, 0xf6, 0xda, 0x00, 0xc9, 0x6f, 0xa2, 0xca, 0x9f, + 0x43, 0x4f, 0x76, 0x53, 0xbe, 0xe7, 0x28, 0x92, 0xb9, 0xd8, 0x33, 0xc9, 0x8f, 0x98, 0x8b, 0xfd, + 0xec, 0x63, 0x22, 0xe6, 0x62, 0x5f, 0x7b, 0x8c, 0xe8, 0xb9, 0xe8, 0x6a, 0xd6, 0xe7, 0x30, 0xda, + 0xe8, 0x37, 0x25, 0x18, 0x0e, 0x64, 0xc4, 0xe8, 0xf1, 0x9e, 0x82, 0x76, 0xda, 0x30, 0x74, 0x7f, + 0xb1, 0xd9, 0x3d, 0xe1, 0x96, 0x17, 0xa9, 0x2e, 0xf3, 0x68, 0xee, 0x30, 0xba, 0x58, 0x01, 0x89, + 0xbf, 0x21, 0xc1, 0x78, 0x87, 0x2c, 0x33, 0x62, 0x16, 0x76, 0x4f, 0x9a, 0xf3, 0xe7, 0x0f, 0x4e, + 0xc8, 0xb5, 0xba, 0x48, 0xb5, 0xfa, 0x09, 0xf4, 0xcc, 0x61, 0xb4, 0xf2, 0xad, 0xcf, 0x37, 0xbd, + 0x03, 0xd1, 0xbe, 0x7e, 0xd0, 0xb9, 0x03, 0x0a, 0x26, 0x14, 0x7a, 0xea, 0xc0, 0x74, 0x5c, 0x9f, + 0x17, 0xa8, 0x3e, 0xcf, 0xa3, 0xd5, 0x1f, 0x4e, 0x9f, 0xf6, 0x65, 0xfd, 0x8b, 0xed, 0x57, 0xf3, + 0x7b, 0x7b, 0x51, 0xc7, 0x64, 0x35, 0xff, 0xc4, 0x81, 0x68, 0xb8, 0x52, 0xe7, 0xa9, 0x52, 0x67, + 0xd0, 0x63, 0xdd, 0x94, 0xf2, 0x9d, 0x7a, 0xd7, 0xf4, 0x6d, 0x63, 0xf6, 0x9d, 0x2c, 0x05, 0x7e, + 0x37, 0xfa, 0x29, 0x71, 0xe2, 0xf8, 0x54, 0xcf, 0x7e, 0x7d, 0x79, 0x6c, 0xfe, 0xa1, 0x3e, 0x30, + 0xb9, 0x5c, 0xf7, 0x51, 0xb9, 0x26, 0xd1, 0xc9, 0x6e, 0x72, 0x91, 0x5c, 0x16, 0x7d, 0x50, 0x72, + 0x2f, 0x29, 0x9c, 0xee, 0xcd, 0xdb, 0x9f, 0xec, 0x76, 0x3f, 0xe8, 0xd0, 0x21, 0x05, 0x96, 0x1f, + 0xa0, 0x92, 0x4c, 0xa3, 0xc9, 0xae, 0x92, 0xb0, 0xd4, 0xf7, 0x76, 0x9f, 0x1c, 0xf8, 0xd3, 0xc1, + 0xae, 0x1f, 0xaf, 0xa8, 0x63, 0x1d, 0xdb, 0x9a, 0x7d, 0xa8, 0x8f, 0x57, 0xf4, 0xf7, 0x7a, 0xea, + 0x77, 0x93, 0x90, 0x59, 0x60, 0xbd, 0xac, 0x3b, 0xaa, 0xf3, 0x43, 0x6e, 0x04, 0x90, 0xcd, 0xbf, + 0xc9, 0xc6, 0x3e, 0x15, 0xe9, 0x7d, 0xfc, 0x30, 0x73, 0xa0, 0x6b, 0xdb, 0xec, 0x90, 0x20, 0xbf, + 0x21, 0x1d, 0xe6, 0x27, 0xb3, 0xcf, 0xbb, 0xd1, 0xb3, 0x0b, 0xec, 0x23, 0x8f, 0xef, 0x93, 0xe0, + 0x28, 0xc5, 0xf2, 0xe6, 0x1b, 0xc5, 0x14, 0x77, 0xf6, 0xba, 0x7a, 0xcc, 0x92, 0xea, 0x2b, 0xc1, + 0xb0, 0xcf, 0x32, 0xde, 0xc7, 0xef, 0xb3, 0x9c, 0xf4, 0x75, 0x1e, 0x66, 0x2b, 0x2b, 0xe3, 0x8d, + 0x36, 0x4a, 0x3b, 0xb4, 0xaf, 0x4f, 0x1c, 0x7e, 0x5f, 0xff, 0x1c, 0x0c, 0xf9, 0x22, 0x7d, 0x2e, + 0x19, 0x71, 0xcd, 0x34, 0x5c, 0x44, 0xf3, 0x13, 0xa3, 0xf7, 0x4b, 0x70, 0xb4, 0xe3, 0x22, 0x48, + 0xff, 0x17, 0xed, 0x01, 0x8b, 0x74, 0x21, 0xe3, 0x74, 0xe4, 0x2b, 0x2b, 0x13, 0xad, 0x4e, 0xd9, + 0xc4, 0x1a, 0x0c, 0x07, 0x16, 0xb0, 0x9c, 0xf8, 0x8f, 0xd2, 0xfd, 0xdf, 0xb0, 0x08, 0x32, 0x40, + 0x79, 0x48, 0xe1, 0x3d, 0xd3, 0xb0, 0x1c, 0x5c, 0xa3, 0x47, 0x1e, 0x52, 0x8a, 0xdb, 0x96, 0x57, + 0x00, 0xb5, 0x0f, 0x6e, 0xf8, 0x3b, 0xa4, 0x69, 0xef, 0x3b, 0xa4, 0x13, 0x90, 0xf4, 0x7f, 0xa9, + 0x93, 0x35, 0xbc, 0x3a, 0xc5, 0xed, 0x9e, 0xf3, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x43, 0x89, + 0xb3, 0x44, 0x22, 0x94, 0x00, 0x00, } r := bytes.NewReader(gzipped) gzipr, err := compress_gzip.NewReader(r)